diff --git a/.gitignore b/.gitignore index 05588e2..aea023b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,13 @@ # Own stuff build/ Makefile -.vscode/ external/lemon/ external/lemon.tar.gz # Python __pycache__ +out/ +logs/ # Prerequisites *.d @@ -40,3 +41,5 @@ __pycache__ *.exe *.out *.app + +.vscode/* diff --git a/.gitmodules b/.gitmodules index 42d7939..a311246 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "external/eigen"] path = external/eigen url = https://gitlab.com/libeigen/eigen.git +[submodule "external/thread-pool"] + path = external/thread-pool + url = https://github.com/bshoshany/thread-pool diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..e50cbb8 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,26 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +# Python 3.9 problem: see https://github.com/readthedocs/readthedocs.org/issues/7554#issuecomment-785114155 +build: + os: ubuntu-20.04 + tools: + python: "3.9" + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: python/docs/source/conf.py + +# If using Sphinx, optionally build your docs in additional formats such as PDF +formats: + - pdf + +# Optionally declare the Python requirements required to build your docs +# python: +# install: +# - requirements: docs/requirements.txt \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..ce7d0a1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "python.formatting.autopep8Args": [ + "--max-line-length", + "100" + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c3e060..7b00236 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,24 +6,31 @@ option(MAJORMINER_BUILD_TESTS "Build majorminer test executable" ON) enable_language(C CXX) set(CMAKE_CXX_STANDARD 20) set(CXX_STANDARD_REQUIRED ON) -set(CMAKE_BUILD_TYPE Debug) -set(MM_INCLUDE_LIBS external/oneTBB/include external/eigen build/external/lemon/ external/lemon/ src/) +set(CMAKE_BUILD_TYPE Release) +set(MM_INCLUDE_LIBS external/oneTBB/include external/eigen build/external/lemon/ external/lemon/ external/ src/) set(MM_LINK_LIBS TBB::tbb lemon) # neither build tests nor tbbmalloc in oneTBB set(TBB_TEST CACHE BOOL OFF) set(TBBMALLOC_BUILD CACHE BOOL OFF) +set(TBB_DISABLE_HWLOC_AUTOMATIC_SEARCH CACHE BOOL OFF) + +set(LEMON_ENABLE_GLPK CACHE BOOL OFF) +set(LEMON_ENABLE_ILOG CACHE BOOL OFF) +set(LEMON_ENABLE_ILOG CACHE BOOL OFF) +set(LEMON_ENABLE_COIN CACHE BOOL OFF) +set(LEMON_ENABLE_SOPLEX CACHE BOOL OFF) + # build NetworkSimplex, gtest and oneTBB add_subdirectory(external) - if ( CMAKE_COMPILER_IS_GNUCC ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -fdiagnostics-color=always") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Werror -fdiagnostics-color=always") endif() if ( MSVC ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /WX") endif() add_library(majorminer) diff --git a/README.md b/README.md index 662bb76..fc176f8 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,24 @@ -# majorminer +# graph-embedder +[![Documentation Status](https://readthedocs.org/projects/majorminer/badge/?version=latest)](https://majorminer.readthedocs.io/en/latest/?badge=latest) + + Testing a bunch of graph minor embedding heuristics and related techniques to improve the embedding of QUBOs. +Our final results for the project can be found [here](doc/Studienarbeit.pdf). + -| :warning: | This is a research repo, so APIs and algorithms might change frequently as were are trying out different ideas. Moreover, this means that the code is not production-ready. | + +| :warning: | This is a research repo, so APIs and algorithms might change frequently as we are trying out different ideas. Moreover, this means that the code is not production-ready. | |---------------|:------------------------| | :point_up: | We currently do not implement the same approaches in C++ and Python, but try out different ideas in different programming languages. Make sure to check out both the C++ and Python implementation. | |---------------|:------------------------| +# Python +All Python-related code and documentation can be found [in the Python folder](python/). - -
- C++ - -# Build C++ library +# C++ +## Build C++ library Note that in order to build, you have to clone the submodules as well. That is, if you have already cloned this repository, you should run ```git submodule update --init --recursive``` and find the submodules in ```external/```. In the case, you are about to clone the repository, just run ```git clone --recursive https://github.com/MinorEmbedding/majorminer.git```. @@ -27,17 +32,10 @@ cmake .. -DMAJORMINER_BUILD_TESTS=[ON|OFF] # depending on whether you want to ru make ``` -# Libraries used in the C++-Project +## Libraries used in the C++-Project #### [oneTBB](https://github.com/oneapi-src/oneTBB) (License: [Apache 2.0](https://choosealicense.com/licenses/apache-2.0/)) #### [GoogleTest](https://github.com/google/googletest) (License: [BSD 3-Clause "New" or "Revised"](https://choosealicense.com/licenses/bsd-3-clause/)) #### [LEMON](https://lemon.cs.elte.hu/trac/lemon) (License: [Boost Software License 1.0](https://choosealicense.com/licenses/bsl-1.0/)) #### [Eigen](https://eigen.tuxfamily.org/index.php?title=Main_Page) (License: [MPL2](https://choosealicense.com/licenses/mpl-2.0/), disabled LGPL features.) -
- +#### [thread-pool](https://github.com/bshoshany/thread-pool) (License: [MIT](https://choosealicense.com/licenses/mit/)) - -
-Python - -All Python-related code and documentation can be found [in the Python folder](python/). -
diff --git a/doc/Studienarbeit.pdf b/doc/Studienarbeit.pdf new file mode 100755 index 0000000..0e91377 Binary files /dev/null and b/doc/Studienarbeit.pdf differ diff --git a/external/thread-pool b/external/thread-pool new file mode 160000 index 0000000..b6cd773 --- /dev/null +++ b/external/thread-pool @@ -0,0 +1 @@ +Subproject commit b6cd773f37b1be7718f771ae7403726a28be5f40 diff --git a/img/chimera_clique_12_95.svg b/img/chimera_clique_12_95.svg new file mode 100644 index 0000000..6b26fb2 --- /dev/null +++ b/img/chimera_clique_12_95.svg @@ -0,0 +1,2 @@ +Iteration 95: ReduceOverlap applied on 7. + \ No newline at end of file diff --git a/img/chimera_clique_15_170.svg b/img/chimera_clique_15_170.svg new file mode 100644 index 0000000..1b68a2b --- /dev/null +++ b/img/chimera_clique_15_170.svg @@ -0,0 +1,2 @@ +Iteration 170: ReduceOverlap applied on 13. + \ No newline at end of file diff --git a/img/chimera_clique_18_211.svg b/img/chimera_clique_18_211.svg new file mode 100644 index 0000000..9da4d72 --- /dev/null +++ b/img/chimera_clique_18_211.svg @@ -0,0 +1 @@ +Iteration 211: Complex adjacent node 17 (17) \ No newline at end of file diff --git a/img/chimera_clique_21_302.svg b/img/chimera_clique_21_302.svg new file mode 100644 index 0000000..4bb4bed --- /dev/null +++ b/img/chimera_clique_21_302.svg @@ -0,0 +1,2 @@ +Iteration 302: ReduceOverlap applied on 14. + \ No newline at end of file diff --git a/img/chimera_clique_25_421.svg b/img/chimera_clique_25_421.svg new file mode 100644 index 0000000..65ddd27 --- /dev/null +++ b/img/chimera_clique_25_421.svg @@ -0,0 +1,2 @@ +Iteration 421: Final iteration. Distinct overlaps: 0; Total overlaps: 0 + \ No newline at end of file diff --git a/img/chimera_clique_28_543.svg b/img/chimera_clique_28_543.svg new file mode 100644 index 0000000..86098ec --- /dev/null +++ b/img/chimera_clique_28_543.svg @@ -0,0 +1,2 @@ +Iteration 543: Final iteration. Distinct overlaps: 0; Total overlaps: 0 + \ No newline at end of file diff --git a/img/chimera_clique_31_653.svg b/img/chimera_clique_31_653.svg new file mode 100644 index 0000000..2dd136f --- /dev/null +++ b/img/chimera_clique_31_653.svg @@ -0,0 +1,2 @@ +Iteration 653: Final iteration. Distinct overlaps: 0; Total overlaps: 0 + \ No newline at end of file diff --git a/img/chimera_clique_33_767.svg b/img/chimera_clique_33_767.svg new file mode 100644 index 0000000..67c3a66 --- /dev/null +++ b/img/chimera_clique_33_767.svg @@ -0,0 +1,2 @@ +Iteration 767: Final iteration. Distinct overlaps: 0; Total overlaps: 0 + \ No newline at end of file diff --git a/img/chimera_clique_34_799.svg b/img/chimera_clique_34_799.svg new file mode 100644 index 0000000..b657d38 --- /dev/null +++ b/img/chimera_clique_34_799.svg @@ -0,0 +1,2 @@ +Iteration 799: Final iteration. Distinct overlaps: 0; Total overlaps: 0 + \ No newline at end of file diff --git a/img/chimera_clique_8_19.svg b/img/chimera_clique_8_52.svg similarity index 70% rename from img/chimera_clique_8_19.svg rename to img/chimera_clique_8_52.svg index 7fa9772..d91669c 100644 --- a/img/chimera_clique_8_19.svg +++ b/img/chimera_clique_8_52.svg @@ -1 +1,2 @@ -Iteration 19: FrontierShifting. Conqueror 3, victim 4, contested 42 \ No newline at end of file +Iteration 52: ReduceOverlap applied on 1. + \ No newline at end of file diff --git a/include/majorminer_lib.hpp b/include/majorminer_lib.hpp new file mode 100644 index 0000000..883a53b --- /dev/null +++ b/include/majorminer_lib.hpp @@ -0,0 +1,15 @@ +#ifndef __MAJORMINER_MAJORMINER_LIB_HPP_ +#define __MAJORMINER_MAJORMINER_LIB_HPP_ + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#endif \ No newline at end of file diff --git a/python/Dockerfile b/python/Dockerfile new file mode 100644 index 0000000..064a675 --- /dev/null +++ b/python/Dockerfile @@ -0,0 +1,12 @@ +FROM python:3.9.10 +WORKDIR /app + +RUN mkdir /app/out +RUN mkdir /app/logs + +COPY requirements.txt . +RUN pip install -r requirements.txt + +COPY ./src /app/src + +ENTRYPOINT [ "python", "-m", "src.solver.evolution" ] \ No newline at end of file diff --git a/python/README.md b/python/README.md index 31e3a40..027fd41 100644 --- a/python/README.md +++ b/python/README.md @@ -1,5 +1,8 @@ # Python evolutionary embedding +| :warning: | This Readme is currently outdated. You can find the [documentation here](https://majorminer.readthedocs.io/)| +|---------------|:------------------------| + ## Usage Execute (from within the python folder): @@ -16,4 +19,4 @@ In order to get **144 unique K4 embeddings on a single chimera cell**, execute ( python -m src.solver.k4_results ``` -![144 unique K4 embeddings on a single chimera cell](./images/k4_embedding.svg) \ No newline at end of file +![144 unique K4 embeddings on a single chimera cell](./images/k4_embedding.svg) diff --git a/python/docs/Majorminer Python class diagram.drawio b/python/docs/Majorminer Python class diagram.drawio new file mode 100644 index 0000000..7e1f2c3 --- /dev/null +++ b/python/docs/Majorminer Python class diagram.drawio @@ -0,0 +1 @@ +7Vtdc9o4FP01zOw+pGPZfPURCEmbpiktabNvjLAFVpEtVhYh5Nf3ypYxRkBMFgJLmMlkrGtZsu85ks+RRclpBU/XAo/9r9wjrGRb3lPJuSzZdg1V4b8KzJJAGX1MAkNBvSSEskCXPhMdtHR0Qj0S5SpKzpmk43zQ5WFIXJmLYSH4NF9twFm+1zEeEiPQdTEzow/Uk34Srdu1LP6J0KGf9oyq+vkCnFbWTxL52OPThZDTLjktwblMjoKnFmEqd2leHj7PHtjtqHp98z36F/9sfrm/+3WRNHa1zSXzRxAklK9u+nk0uPr0q/z7n3Hn6vvUum70by70JdYjZhOdr5+hRwUAQbyYDw3v9y2NpM6AnKVpjaY0YDiEUnPAQ9nVZxCUMaPDEI5duFsiIPBIhKSASEOfkHwMUdenzLvFMz5RzxRJ7I7SUtPngj5Ds5jpNuG0kJpcdjVXo6uuhLAFUUEiqNNJE4XmoVscSV3H5YzhcUT78xsOsBjSsMml5EHaEJ+EHvF0aY58XJCCj+ZcUtcXhEfDqLJBnhbIqeG6JjwgUsygij5rOxoePfRQWp5mREZVHfMXSVwt6wGkB89w3va8ux+AMQ6HkISsP3upP7tgf3Y13x1mAHyIJWmqNEaLtISDhUfNQjFZtyAuMoh7hwNi0BQyLRcoychAriVkNMYuDYe3cZ3Lchb5oZ9UhThcO2AxGXzqeSSMySKxxAmfFEPGnIYyTkWlCX+QsJb1oVKqwA21oIyyMvyp6kK2eAi8wjQmEAGyToki7ApqbRzGL1NrlkdsW2QXiZSDdFv8bAO/js9DRca7SdCHaePUkNwwo/gyYPpwX3hX7LfDu35Rrt/41K98Cab3d21+83g5uCif8V6Pt4FjUQqsxbtWP/D4dgy82wGm6rKG58E7OXrXgO9+gCOrfGDEzRFuQMxoLBh1OtBKMfUC/gEgqZpLAb9XfLi8QAYpHJMUzgoCMNwnrMMjKilX7Yuk7hIxDvWaLqz46nsCtWJO2xPh+jhSMzfo7BGkNz46wQG9P1APPTlXDVS7cuKpxyxo86yzzdudzUNLtsupFrV5zoZhv97moSVb6dSP1+bV1jP1VIVjwWmnWphmx2L56gaWDbh7tXxnW1/hVXJySO5UEW6N91tavpV3/PEsCHcOalFfty89mK7qL4D6GSZ+qw1o0D6OXzP3XAVCwVVzJzakF0VQeV8g1w89UyNzdfWaqFdulwQ0xEIhfo9HkOxTw3dfkCJ06Nk4vYFN0zEJvYb65AalPuNKbjchpPU4spLiFWXpq+sFwZx//xFvSNKhQ1ifT9tZoBkH4ETKlK3ldsTBl5KXIQODMSQF7Jy6243ArgJSEIYlfcx/edwgzjuKuJkwt628MLctJ99E8pD6KnvhU9+2DSVZMBra2ccZc/WvI/iARBE39frZYu7fYjrLlq+oxaxZL5J4hcN0ygUcZu04HCYy1y27mGE9477Dd9t88P5/nCUylykN9N671dge1qIGcm9ew1ymfFeKJUXsqCULWprpa6+ULM5SQ3Zt6V72LVnMlUa99akdQssPVPotHknzK8d5I9T+5Uul8tqNSdar9IvRX7lofwfQL+ayak/yXsjjXZcNRVYi//r73aqZWmGyHY2aMRdOe24898RwetQ9RTx3uli+PeoHXy23Tc981rD/GdZDr5fbprvEntdTUg1m6RMcxntD8uCL4rZpMgUJIL1nNLdH803Xw1duSDU/cYC96AmCXV/l8mTBfM1e0wTf49jQtBJM89tGDszeFOxboqHOuG6Ba/UN95SuxNX82twIoTyZ/0YJCvHPlAxQQUCO1WHIpVI7U59K0gWoVGwKV+RlVB+c8zBWoN8mMlFZcdzDYvRNASxVSqwPVkUhnrjvWtHUr/fAhbeEIeujgUR9BRBok99dgwQUs9+wJa40+yGg0/4D \ No newline at end of file diff --git a/python/docs/make.bat b/python/docs/make.bat new file mode 100644 index 0000000..e5baf6b --- /dev/null +++ b/python/docs/make.bat @@ -0,0 +1,37 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd + +pause diff --git a/python/src/graphs/__init__.py b/python/docs/source/_static/.gitkeep similarity index 100% rename from python/src/graphs/__init__.py rename to python/docs/source/_static/.gitkeep diff --git a/python/docs/source/_static/embedding_solver_principle.png b/python/docs/source/_static/embedding_solver_principle.png new file mode 100644 index 0000000..1435031 Binary files /dev/null and b/python/docs/source/_static/embedding_solver_principle.png differ diff --git a/python/docs/source/_static/python_architecture.png b/python/docs/source/_static/python_architecture.png new file mode 100644 index 0000000..99b8eae Binary files /dev/null and b/python/docs/source/_static/python_architecture.png differ diff --git a/python/docs/source/_templates/.gitkeep b/python/docs/source/_templates/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/python/docs/source/api.rst b/python/docs/source/api.rst new file mode 100644 index 0000000..9f96d28 --- /dev/null +++ b/python/docs/source/api.rst @@ -0,0 +1,31 @@ +.. _api: + +API Reference +============= + + +Graph Module +------------ + +.. automodule:: src.graph.undirected_graph + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: src.graph.embedding_graph + :members: + :undoc-members: + :show-inheritance: + +.. automodule:: src.graph.chimera_graph + :members: + :undoc-members: + :show-inheritance: + + +More Modules +------------ + +.. note:: + + To come soon... \ No newline at end of file diff --git a/python/docs/source/conf.py b/python/docs/source/conf.py new file mode 100644 index 0000000..286b36e --- /dev/null +++ b/python/docs/source/conf.py @@ -0,0 +1,82 @@ +# Great tutorial for this setup +# https://samnicholls.net/2016/06/15/how-to-sphinx-readthedocs/#fn-841-5 + +# In order to build run the following commands: +# luckily ReadTheDocs is doing this automatically for us + +# https://stackoverflow.com/a/46349694 +# cd docs/ +# sphinx-apidoc -o source/ ../src -f +# and after that run: +# ./make.bat html + + +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + +# https://stackoverflow.com/a/44980548 +sys.path.insert(0, os.path.abspath('../..')) + + +# -- Project information ----------------------------------------------------- + +project = 'majorminer' +copyright = '2021, Dominic Plein, Julien Meier' +author = 'Dominic Plein, Julien Meier' + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.autosummary" +] + +# Napoleon setup +napoleon_google_docstring = True # defaults to True +napoleon_use_ivar = True + +# Inheritance Diagram +# https://www.sphinx-doc.org/en/master/usage/extensions/inheritance.html +# inheritance_graph_attrs = dict( +# rankdir="TB", +# size='""' +# ) + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = [] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] diff --git a/python/docs/source/index.rst b/python/docs/source/index.rst new file mode 100644 index 0000000..47f2121 --- /dev/null +++ b/python/docs/source/index.rst @@ -0,0 +1,25 @@ +.. majorminer documentation master file + + +Welcome to the documentation of the majorminer research project realized by two students of the DHBW Karlsruhe. This documentation only includes the API for the Python code, NOT the C++ code. + +* :ref:`genindex` +* :ref:`modindex` + + +Overview +======== + +.. toctree:: + :maxdepth: 2 + + overview + + +API Reference +============= + +.. toctree:: + :maxdepth: 2 + + api diff --git a/python/docs/source/modules.rst b/python/docs/source/modules.rst new file mode 100644 index 0000000..e9ff8ac --- /dev/null +++ b/python/docs/source/modules.rst @@ -0,0 +1,7 @@ +src +=== + +.. toctree:: + :maxdepth: 4 + + src diff --git a/python/docs/source/overview.rst b/python/docs/source/overview.rst new file mode 100644 index 0000000..0f16241 --- /dev/null +++ b/python/docs/source/overview.rst @@ -0,0 +1,21 @@ +.. _overview: + +Overview +======== + +Goal +---- + +.. figure:: /_static/embedding_solver_principle.png + :alt: Principle of the embedding solver + + Principle of the embedding solver. Find an embedding for minor H in graph G (in this case: a simple Chimera Graph). Colors indicate different chains (and are not related to the colors in the architecture diagram below). + + +Python architecture +------------------- + +.. figure:: /_static/python_architecture.png + :alt: Python architecture + + Simplified overview over the Python architecture. Grey boxes are classes. \ No newline at end of file diff --git a/python/docs/source/src.drawing.rst b/python/docs/source/src.drawing.rst new file mode 100644 index 0000000..6aef7e7 --- /dev/null +++ b/python/docs/source/src.drawing.rst @@ -0,0 +1,21 @@ +src.drawing package +=================== + +Submodules +---------- + +src.drawing.draw module +----------------------- + +.. automodule:: src.drawing.draw + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: src.drawing + :members: + :undoc-members: + :show-inheritance: diff --git a/python/docs/source/src.embedding.rst b/python/docs/source/src.embedding.rst new file mode 100644 index 0000000..07a6f81 --- /dev/null +++ b/python/docs/source/src.embedding.rst @@ -0,0 +1,29 @@ +src.embedding package +===================== + +Submodules +---------- + +src.embedding.embedding module +------------------------------ + +.. automodule:: src.embedding.embedding + :members: + :undoc-members: + :show-inheritance: + +src.embedding.graph\_mapping module +----------------------------------- + +.. automodule:: src.embedding.graph_mapping + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: src.embedding + :members: + :undoc-members: + :show-inheritance: diff --git a/python/docs/source/src.graph.rst b/python/docs/source/src.graph.rst new file mode 100644 index 0000000..c3005ba --- /dev/null +++ b/python/docs/source/src.graph.rst @@ -0,0 +1,29 @@ +src.graph package +================= + +Submodules +---------- + +src.graph.chimera\_graph module +------------------------------- + +.. automodule:: src.graph.chimera_graph + :members: + :undoc-members: + :show-inheritance: + +src.graph.undirected\_graph module +---------------------------------- + +.. automodule:: src.graph.undirected_graph + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: src.graph + :members: + :undoc-members: + :show-inheritance: diff --git a/python/docs/source/src.rst b/python/docs/source/src.rst new file mode 100644 index 0000000..c2c6678 --- /dev/null +++ b/python/docs/source/src.rst @@ -0,0 +1,21 @@ +src package +=========== + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + src.drawing + src.embedding + src.graph + src.solver + +Module contents +--------------- + +.. automodule:: src + :members: + :undoc-members: + :show-inheritance: diff --git a/python/docs/source/src.solver.rst b/python/docs/source/src.solver.rst new file mode 100644 index 0000000..022dcf5 --- /dev/null +++ b/python/docs/source/src.solver.rst @@ -0,0 +1,37 @@ +src.solver package +================== + +Submodules +---------- + +src.solver.embedding\_solver module +----------------------------------- + +.. automodule:: src.solver.embedding_solver + :members: + :undoc-members: + :show-inheritance: + +src.solver.evolution module +--------------------------- + +.. automodule:: src.solver.evolution + :members: + :undoc-members: + :show-inheritance: + +src.solver.k4\_results module +----------------------------- + +.. automodule:: src.solver.k4_results + :members: + :undoc-members: + :show-inheritance: + +Module contents +--------------- + +.. automodule:: src.solver + :members: + :undoc-members: + :show-inheritance: diff --git a/python/plots/graphs/k_graph.py b/python/plots/graphs/k_graph.py new file mode 100644 index 0000000..a4786df --- /dev/null +++ b/python/plots/graphs/k_graph.py @@ -0,0 +1,29 @@ +import matplotlib.pyplot as plt +import networkx as nx + + +def draw_k_graph(n: int): + G = nx.complete_graph(n) + pos = nx.circular_layout(G) + + fig, ax = plt.subplots(figsize=(5, 5)) + plt.tight_layout() + + # nx.draw(G) + nx.draw_networkx_nodes(G, + pos=pos, + node_size=500, + node_color='#5B5B5B', + linewidths=3, + edgecolors='#858585') + nx.draw_networkx_edges(G, + pos=pos, + width=2, + style='solid', + edge_color='#5B5B5B') + + plt.savefig(f'./out/k{i}.pdf', bbox_inches='tight', pad_inches=0) + + +for i in range(1, 41): + draw_k_graph(i) diff --git a/python/plots/how_many_generations/data/evolution_different_probabilities_extend_to_free.py b/python/plots/how_many_generations/data/evolution_different_probabilities_extend_to_free.py new file mode 100644 index 0000000..73a5d80 --- /dev/null +++ b/python/plots/how_many_generations/data/evolution_different_probabilities_extend_to_free.py @@ -0,0 +1,117 @@ +# Move this file to src/solver to start + +import logging +import multiprocessing +import os +import time +from functools import partial +from random import random +from typing import Optional + +import numpy as np +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + + +################################# Params ####################################### + +max_total = 50 +max_generations = 600 +remove_redundancy_probability = 0.01 + +# Chimera graph +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + + +############################### Evolution ###################################### + +def different_params(): + for extend_to_free_probability in np.linspace(0, 1.0, 10): + print(f'Started with probability {extend_to_free_probability}') + graph = TestGraph.k(8) + start_time = time.time() + start_multiprocessing((graph, extend_to_free_probability), + f'k8_extend_to_free_prob_{extend_to_free_probability}') + duration = time.time() - start_time + print(f'Duration using probability {extend_to_free_probability}: {duration} s') + + +def start_multiprocessing(plot_params, name: str): + processes = multiprocessing.cpu_count() * int(os.getenv('CORE_PERCENTAGE', 75)) // 100 + with multiprocessing.Pool(processes) as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, plot_params), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/how_many_generations_{m}x{n}_{max_total}_{max_generations}_max_gen_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(plot_params, j) -> int: + solver = EmbeddingSolver(plot_params[0], m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver, plot_params) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver, plot_params) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + evo_params = EvolutionParams( + population_size=4, + max_mutation_trials=30, + mutation_extend_to_free_neighbors_probability=plot_params[1] # should be <=0.5 + ) + + child = solver.generate_population_and_select(evo_params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + + +if __name__ == "__main__": + different_params() diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.0.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.0.txt new file mode 100644 index 0000000..cc6b276 --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.0.txt @@ -0,0 +1,50 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +30 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +77 +77 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +166 +193 +140 +238 +369 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.11.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.11.txt new file mode 100644 index 0000000..e51d618 --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.11.txt @@ -0,0 +1,50 @@ +36 +54 +72 +202 +97 +54 +237 +-1 +-1 +195 +90 +71 +66 +115 +111 +146 +15 +17 +225 +44 +347 +110 +52 +79 +125 +141 +95 +201 +87 +71 +30 +111 +72 +43 +109 +93 +67 +236 +475 +155 +176 +161 +50 +71 +25 +188 +210 +-1 +296 +-1 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.22.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.22.txt new file mode 100644 index 0000000..1f62b11 --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.22.txt @@ -0,0 +1,50 @@ +41 +80 +135 +130 +238 +119 +207 +298 +49 +180 +160 +566 +226 +63 +74 +-1 +108 +346 +78 +63 +87 +160 +99 +315 +33 +425 +-1 +46 +100 +125 +43 +-1 +116 +111 +-1 +238 +99 +122 +298 +113 +44 +369 +-1 +106 +67 +540 +352 +-1 +-1 +539 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.33.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.33.txt new file mode 100644 index 0000000..b8ea03c --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.33.txt @@ -0,0 +1,50 @@ +77 +90 +77 +169 +160 +261 +31 +168 +217 +204 +245 +388 +175 +233 +65 +91 +232 +79 +181 +168 +114 +49 +14 +292 +186 +44 +191 +207 +35 +222 +-1 +230 +56 +217 +181 +51 +160 +109 +25 +-1 +147 +222 +-1 +61 +31 +80 +-1 +115 +339 +-1 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.44.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.44.txt new file mode 100644 index 0000000..568a5bb --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.44.txt @@ -0,0 +1,50 @@ +138 +149 +185 +70 +59 +286 +153 +47 +36 +59 +17 +-1 +530 +-1 +66 +17 +116 +84 +64 +16 +76 +-1 +27 +227 +-1 +477 +47 +75 +185 +304 +188 +247 +-1 +120 +186 +115 +50 +55 +250 +156 +313 +97 +146 +47 +82 +-1 +418 +442 +-1 +-1 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.56.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.56.txt new file mode 100644 index 0000000..0add582 --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.56.txt @@ -0,0 +1,50 @@ +45 +70 +138 +174 +71 +229 +134 +52 +111 +200 +46 +74 +344 +161 +342 +171 +228 +195 +-1 +37 +249 +45 +153 +72 +58 +88 +250 +264 +89 +380 +42 +252 +-1 +-1 +30 +381 +159 +94 +241 +187 +57 +154 +-1 +143 +236 +-1 +163 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.67.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.67.txt new file mode 100644 index 0000000..431f4d0 --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.67.txt @@ -0,0 +1,50 @@ +68 +168 +193 +15 +141 +80 +210 +105 +105 +334 +-1 +321 +435 +185 +369 +232 +236 +138 +137 +-1 +29 +133 +199 +-1 +138 +15 +204 +29 +148 +102 +156 +234 +-1 +132 +-1 +68 +273 +147 +-1 +54 +464 +203 +176 +84 +176 +-1 +279 +-1 +568 +-1 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.78.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.78.txt new file mode 100644 index 0000000..3972e56 --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.78.txt @@ -0,0 +1,50 @@ +14 +149 +282 +-1 +260 +161 +-1 +16 +78 +479 +278 +55 +143 +89 +-1 +122 +170 +-1 +15 +19 +54 +-1 +-1 +86 +296 +62 +303 +497 +535 +251 +-1 +476 +-1 +-1 +88 +298 +125 +45 +42 +-1 +162 +-1 +79 +36 +47 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.89.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.89.txt new file mode 100644 index 0000000..6e28c9f --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_0.89.txt @@ -0,0 +1,50 @@ +53 +99 +113 +148 +52 +180 +258 +245 +165 +-1 +-1 +305 +594 +-1 +-1 +21 +259 +249 +-1 +100 +76 +332 +390 +362 +-1 +98 +513 +292 +233 +194 +329 +-1 +41 +72 +-1 +-1 +-1 +101 +30 +279 +229 +-1 +216 +-1 +-1 +-1 +-1 +306 +423 +-1 diff --git a/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_1.0.txt b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_1.0.txt new file mode 100644 index 0000000..fa21d68 --- /dev/null +++ b/python/plots/how_many_generations/data/extend_to_free_prob_50_runs/how_many_generations_5x5_50_600_max_gen_k8_extend_to_free_prob_1.0.txt @@ -0,0 +1,50 @@ +28 +242 +254 +287 +-1 +-1 +440 +-1 +-1 +182 +-1 +88 +-1 +-1 +89 +417 +121 +52 +-1 +270 +489 +-1 +-1 +253 +87 +302 +250 +-1 +-1 +-1 +57 +-1 +357 +-1 +-1 +-1 +-1 +23 +290 +-1 +15 +239 +-1 +514 +296 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k10.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k10.txt new file mode 100644 index 0000000..033cb5b --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k10.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k2.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k2.txt new file mode 100644 index 0000000..257325e --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k2.txt @@ -0,0 +1,1000 @@ +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k3.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k3.txt new file mode 100644 index 0000000..eb657d0 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k3.txt @@ -0,0 +1,1000 @@ +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +1 +3 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +5 +3 +1 +1 +1 +1 +1 +5 +1 +1 +1 +1 +1 +1 +4 +4 +4 +1 +4 +1 +1 +3 +4 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +6 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +1 +1 +4 +1 +3 +1 +1 +1 +1 +1 +7 +4 +1 +1 +1 +1 +10 +1 +1 +1 +1 +3 +1 +5 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +6 +1 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +4 +1 +3 +1 +5 +1 +1 +1 +1 +1 +1 +5 +4 +3 +1 +1 +1 +5 +1 +1 +4 +1 +6 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +5 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +5 +1 +3 +5 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +6 +1 +1 +1 +1 +1 +1 +1 +1 +3 +4 +1 +1 +1 +1 +5 +1 +1 +1 +8 +1 +5 +3 +1 +1 +1 +1 +1 +4 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +5 +1 +1 +1 +3 +1 +4 +1 +1 +1 +1 +1 +3 +5 +1 +1 +4 +1 +1 +4 +3 +1 +1 +1 +3 +1 +1 +1 +1 +1 +4 +5 +1 +1 +9 +1 +1 +1 +1 +1 +1 +1 +5 +1 +1 +1 +1 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +9 +1 +3 +1 +1 +1 +1 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +6 +1 +5 +1 +3 +1 +1 +1 +1 +5 +1 +1 +1 +6 +1 +1 +1 +1 +1 +4 +5 +1 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +6 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +3 +1 +1 +1 +6 +1 +3 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +6 +6 +1 +1 +1 +5 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +5 +1 +1 +4 +3 +1 +1 +1 +1 +1 +1 +3 +7 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +6 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +4 +1 +1 +3 +3 +1 +1 +8 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +4 +1 +4 +1 +1 +1 +1 +1 +1 +1 +7 +1 +4 +4 +1 +3 +1 +4 +3 +1 +1 +1 +1 +3 +1 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +5 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +8 +1 +3 +1 +1 +1 +1 +1 +1 +4 +5 +1 +1 +1 +1 +4 +1 +3 +1 +1 +1 +1 +1 +3 +4 +3 +1 +3 +1 +1 +1 +1 +1 +1 +1 +5 +1 +1 +3 +4 +1 +1 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +5 +6 +3 +1 +4 +1 +1 +1 +1 +1 +1 +4 +5 +1 +1 +1 +1 +1 +1 +3 +3 +1 +1 +8 +1 +1 +6 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +8 +1 +1 +1 +5 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +4 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +5 +3 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +4 +5 +3 +1 +1 +1 +3 +3 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +4 +3 +1 +1 +1 +4 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +3 +14 +4 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +6 +1 +1 +1 +3 +1 +3 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +6 +1 +1 +1 +1 +4 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +8 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +4 +1 +3 +1 +1 +4 +1 +5 +3 +12 +1 +3 +9 +1 +1 +1 +1 +5 +1 +1 +1 +1 +3 +3 +1 +3 +3 +1 +1 +1 +1 +1 +4 +1 +1 +1 +7 +1 +6 +3 +1 +1 +4 +1 +1 +1 +1 +1 +4 +1 +4 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k4.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k4.txt new file mode 100644 index 0000000..44f41eb --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k4.txt @@ -0,0 +1,1000 @@ +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +9 +2 +2 +2 +8 +2 +2 +2 +2 +2 +5 +2 +2 +9 +2 +2 +2 +2 +11 +2 +2 +10 +2 +2 +2 +2 +2 +2 +8 +5 +2 +2 +2 +5 +2 +10 +2 +12 +2 +7 +2 +2 +2 +2 +5 +2 +9 +12 +10 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +10 +7 +2 +14 +2 +10 +2 +2 +5 +15 +2 +2 +2 +2 +19 +9 +2 +2 +2 +3 +2 +2 +2 +2 +2 +2 +11 +2 +2 +2 +2 +2 +2 +2 +2 +9 +2 +2 +9 +7 +2 +2 +2 +13 +2 +2 +3 +7 +5 +7 +2 +11 +2 +2 +15 +13 +2 +2 +2 +3 +2 +2 +2 +2 +2 +2 +2 +2 +7 +2 +2 +8 +2 +9 +2 +2 +2 +2 +2 +10 +2 +2 +6 +2 +2 +2 +2 +2 +2 +6 +2 +2 +6 +2 +2 +2 +2 +2 +2 +2 +8 +2 +2 +2 +6 +9 +7 +2 +2 +2 +2 +2 +8 +2 +6 +2 +2 +2 +2 +2 +9 +2 +9 +2 +2 +2 +2 +16 +2 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +14 +2 +2 +10 +2 +9 +2 +8 +2 +2 +2 +2 +2 +2 +2 +2 +2 +10 +9 +2 +2 +9 +12 +2 +2 +2 +2 +2 +2 +2 +10 +2 +2 +2 +2 +20 +2 +16 +7 +11 +7 +2 +2 +2 +15 +6 +2 +8 +8 +2 +2 +5 +7 +2 +5 +2 +2 +2 +2 +2 +2 +2 +12 +14 +2 +2 +2 +2 +2 +2 +5 +2 +2 +2 +2 +6 +2 +2 +2 +2 +2 +7 +18 +18 +2 +2 +2 +2 +2 +2 +10 +2 +2 +7 +2 +2 +3 +2 +2 +2 +8 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +8 +2 +2 +2 +8 +2 +2 +2 +2 +2 +7 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +9 +6 +6 +2 +2 +2 +2 +2 +2 +2 +2 +2 +18 +2 +10 +7 +2 +2 +10 +2 +10 +2 +2 +2 +2 +13 +2 +2 +2 +8 +7 +2 +11 +2 +2 +2 +2 +2 +8 +7 +2 +2 +2 +8 +8 +2 +9 +2 +2 +2 +2 +12 +2 +2 +7 +2 +2 +6 +6 +2 +2 +2 +2 +2 +7 +2 +2 +2 +10 +6 +7 +2 +2 +2 +2 +11 +2 +2 +2 +9 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +21 +8 +6 +2 +2 +2 +2 +2 +2 +2 +8 +2 +2 +2 +2 +2 +2 +2 +3 +9 +2 +2 +11 +2 +11 +2 +2 +2 +2 +8 +13 +2 +2 +7 +2 +2 +2 +5 +2 +12 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +6 +2 +2 +6 +2 +11 +2 +2 +2 +2 +2 +2 +2 +2 +9 +2 +2 +2 +7 +2 +2 +2 +15 +20 +6 +2 +2 +2 +2 +2 +2 +2 +2 +2 +9 +7 +2 +2 +2 +2 +2 +6 +2 +2 +2 +2 +19 +2 +2 +9 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +5 +13 +2 +2 +2 +9 +2 +2 +2 +2 +8 +2 +2 +2 +2 +12 +6 +2 +2 +2 +2 +2 +2 +8 +2 +2 +2 +2 +2 +9 +2 +2 +2 +2 +2 +6 +2 +12 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +17 +2 +2 +9 +2 +2 +6 +2 +2 +2 +2 +2 +2 +2 +17 +2 +8 +2 +3 +2 +2 +11 +2 +2 +2 +9 +2 +2 +2 +5 +6 +2 +2 +2 +11 +2 +2 +16 +2 +2 +2 +2 +2 +10 +2 +2 +7 +8 +14 +2 +2 +2 +2 +15 +2 +8 +2 +2 +2 +7 +2 +2 +17 +2 +5 +2 +8 +2 +2 +2 +3 +2 +2 +2 +9 +2 +2 +2 +5 +2 +23 +2 +3 +2 +2 +17 +11 +2 +2 +2 +2 +9 +2 +7 +2 +2 +2 +2 +2 +10 +2 +2 +2 +2 +2 +9 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +9 +2 +2 +2 +6 +2 +2 +2 +2 +2 +2 +2 +11 +2 +2 +2 +2 +2 +8 +2 +2 +2 +2 +6 +2 +2 +2 +2 +2 +2 +2 +8 +14 +7 +2 +12 +5 +7 +2 +2 +2 +2 +2 +2 +15 +2 +18 +2 +11 +2 +2 +7 +11 +12 +2 +2 +2 +16 +2 +2 +10 +2 +2 +2 +2 +11 +2 +9 +7 +2 +2 +8 +2 +2 +2 +2 +2 +2 +2 +11 +2 +2 +8 +2 +2 +9 +2 +6 +2 +2 +2 +2 +11 +2 +2 +7 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +8 +2 +2 +2 +11 +12 +2 +12 +7 +2 +4 +2 +2 +2 +2 +6 +8 +7 +2 +2 +8 +5 +2 +2 +2 +2 +2 +21 +2 +2 +2 +6 +2 +2 +12 +10 +6 +3 +8 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +14 +2 +2 +2 +7 +9 +2 +2 +2 +17 +2 +2 +2 +17 +18 +2 +2 +2 +12 +2 +14 +2 +2 +2 +2 +2 +2 +2 +2 +9 +2 +2 +12 +6 +2 +2 +2 +2 +2 +7 +17 +2 +2 +8 +2 +2 +2 +6 +2 +2 +2 +2 +2 +8 +12 +2 +7 +2 +2 +2 +2 +2 +6 +2 +2 +2 +5 +2 +2 +2 +2 +2 +7 +2 +2 +2 +2 +8 +2 +2 +2 +2 +2 +6 +29 +13 +2 +2 +8 +7 +19 +19 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k5.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k5.txt new file mode 100644 index 0000000..5a76cbe --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k5.txt @@ -0,0 +1,1000 @@ +2 +4 +3 +4 +3 +10 +9 +5 +4 +16 +3 +10 +16 +16 +5 +9 +3 +22 +12 +8 +3 +3 +13 +5 +9 +5 +14 +27 +20 +4 +3 +6 +6 +31 +3 +17 +3 +3 +8 +10 +3 +3 +3 +3 +3 +12 +9 +6 +8 +16 +3 +12 +4 +11 +20 +14 +3 +3 +3 +2 +3 +3 +3 +10 +12 +12 +8 +3 +14 +17 +10 +3 +3 +3 +14 +3 +11 +3 +3 +3 +12 +10 +6 +3 +15 +5 +4 +3 +11 +3 +15 +11 +3 +7 +3 +8 +15 +3 +3 +3 +5 +3 +3 +3 +3 +3 +3 +19 +3 +3 +11 +3 +12 +10 +3 +7 +18 +3 +3 +17 +3 +3 +19 +3 +2 +3 +9 +4 +2 +3 +8 +15 +3 +19 +33 +16 +9 +20 +9 +3 +3 +21 +3 +3 +7 +22 +9 +13 +3 +3 +27 +3 +13 +5 +23 +3 +15 +3 +3 +2 +12 +3 +12 +6 +9 +5 +3 +7 +8 +8 +3 +3 +3 +3 +8 +12 +3 +3 +3 +12 +3 +4 +17 +3 +3 +3 +2 +9 +3 +12 +3 +9 +2 +9 +13 +10 +4 +3 +18 +8 +8 +9 +14 +3 +13 +18 +32 +5 +3 +14 +20 +25 +9 +12 +23 +3 +22 +17 +3 +3 +9 +10 +11 +3 +3 +4 +10 +4 +20 +2 +3 +3 +22 +3 +19 +3 +41 +16 +3 +5 +3 +13 +22 +9 +17 +32 +5 +3 +3 +14 +3 +3 +8 +2 +3 +12 +4 +3 +10 +22 +10 +5 +9 +7 +3 +3 +3 +3 +3 +9 +15 +3 +7 +3 +5 +5 +8 +13 +3 +6 +3 +18 +3 +11 +3 +14 +17 +22 +20 +4 +3 +8 +5 +3 +4 +4 +14 +2 +18 +3 +10 +3 +3 +3 +3 +5 +4 +13 +12 +10 +8 +3 +17 +16 +3 +15 +12 +10 +7 +3 +3 +2 +8 +13 +3 +10 +3 +5 +3 +3 +8 +19 +3 +2 +9 +14 +3 +3 +13 +3 +3 +3 +3 +4 +13 +14 +2 +11 +3 +3 +3 +3 +3 +2 +11 +7 +9 +3 +15 +5 +5 +3 +3 +3 +3 +3 +3 +5 +3 +12 +11 +3 +7 +5 +3 +4 +8 +4 +2 +3 +23 +5 +3 +4 +3 +14 +14 +20 +3 +9 +3 +3 +4 +3 +2 +4 +11 +11 +12 +3 +4 +8 +3 +6 +17 +3 +3 +3 +3 +11 +3 +3 +3 +5 +3 +3 +3 +13 +3 +8 +19 +3 +15 +7 +3 +3 +9 +3 +5 +3 +9 +33 +3 +3 +3 +21 +13 +3 +3 +11 +2 +10 +3 +12 +3 +8 +3 +3 +5 +3 +3 +3 +3 +3 +4 +7 +21 +15 +3 +3 +3 +11 +4 +5 +10 +3 +3 +14 +3 +2 +11 +3 +25 +5 +2 +9 +9 +2 +21 +3 +13 +3 +7 +19 +3 +14 +8 +9 +18 +9 +3 +8 +3 +11 +4 +3 +4 +3 +3 +3 +5 +7 +8 +21 +9 +3 +3 +5 +3 +3 +3 +5 +3 +10 +8 +11 +3 +4 +7 +7 +4 +3 +3 +12 +3 +3 +3 +3 +3 +9 +11 +3 +9 +12 +13 +3 +4 +4 +3 +8 +3 +9 +2 +3 +3 +20 +17 +3 +16 +9 +3 +16 +9 +6 +3 +9 +3 +3 +14 +3 +11 +3 +25 +3 +3 +4 +14 +16 +3 +3 +2 +3 +3 +3 +9 +23 +5 +5 +18 +3 +15 +15 +3 +3 +5 +12 +2 +3 +3 +10 +3 +18 +28 +3 +14 +26 +9 +17 +12 +18 +2 +12 +17 +14 +3 +7 +3 +6 +2 +2 +3 +16 +18 +11 +27 +10 +3 +3 +3 +6 +6 +8 +3 +5 +19 +15 +3 +3 +12 +16 +3 +14 +14 +3 +3 +3 +5 +3 +14 +3 +5 +2 +3 +3 +2 +12 +3 +12 +4 +15 +9 +4 +10 +23 +15 +3 +2 +3 +20 +3 +3 +4 +3 +15 +2 +7 +3 +4 +15 +3 +17 +3 +3 +9 +5 +3 +15 +3 +3 +17 +3 +3 +3 +3 +12 +4 +19 +2 +19 +2 +8 +9 +10 +3 +9 +12 +7 +12 +4 +14 +17 +3 +18 +10 +17 +23 +12 +12 +3 +10 +3 +6 +14 +11 +8 +10 +3 +3 +3 +7 +3 +10 +5 +5 +3 +12 +3 +3 +3 +4 +3 +3 +3 +9 +3 +13 +10 +3 +3 +3 +16 +3 +3 +29 +3 +8 +3 +3 +10 +3 +3 +3 +11 +5 +8 +3 +6 +9 +2 +18 +3 +13 +3 +3 +15 +12 +12 +3 +2 +10 +8 +8 +15 +3 +3 +16 +15 +17 +3 +2 +12 +3 +3 +4 +13 +16 +3 +3 +3 +12 +3 +3 +15 +3 +3 +12 +4 +14 +18 +3 +18 +3 +3 +16 +22 +3 +9 +17 +11 +19 +15 +14 +21 +5 +7 +3 +3 +5 +7 +11 +10 +16 +8 +5 +3 +9 +7 +11 +3 +4 +3 +15 +25 +3 +3 +9 +24 +12 +3 +3 +11 +8 +3 +3 +5 +20 +3 +2 +3 +4 +20 +11 +17 +3 +13 +11 +5 +18 +3 +8 +23 +10 +2 +3 +4 +3 +3 +22 +3 +3 +7 +5 +12 +3 +3 +3 +3 +3 +17 +3 +3 +2 +6 +3 +3 +13 +3 +19 +3 +13 +15 +13 +3 +21 +19 +3 +3 +3 +16 +5 +7 +3 +12 +13 +5 +3 +15 +10 +13 +3 +3 +3 +4 +3 +13 +14 +11 +13 +3 +3 +4 +7 +3 +3 +10 +4 +5 +9 +7 +5 +47 +3 +11 +3 +5 +5 +5 +3 +11 +8 +4 +7 +10 +3 +3 +8 +27 +9 +10 +3 +12 +14 +13 +12 +3 +11 +15 +17 +3 +3 +22 +3 +3 +4 +14 +5 +6 +14 +8 +17 +2 +3 +3 +3 +3 +9 +4 +3 +23 +3 +7 +3 +3 +53 +3 +3 +18 +6 +3 +4 +6 +7 +3 +23 +5 +3 +15 +16 +15 +25 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k6.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k6.txt new file mode 100644 index 0000000..9c65b45 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k6.txt @@ -0,0 +1,1000 @@ +9 +11 +15 +21 +18 +17 +16 +27 +23 +19 +15 +21 +9 +20 +10 +8 +39 +8 +9 +12 +11 +17 +12 +17 +23 +25 +9 +14 +14 +14 +26 +10 +14 +37 +14 +26 +16 +27 +16 +20 +15 +25 +18 +11 +14 +18 +10 +42 +22 +7 +15 +12 +9 +14 +29 +22 +7 +10 +7 +8 +21 +10 +31 +17 +17 +10 +14 +15 +12 +11 +28 +16 +16 +12 +22 +8 +18 +52 +14 +19 +8 +10 +17 +15 +36 +31 +12 +22 +37 +10 +27 +11 +11 +15 +72 +13 +13 +15 +10 +18 +55 +31 +10 +22 +8 +18 +17 +16 +12 +11 +35 +8 +11 +16 +11 +10 +9 +10 +16 +13 +39 +19 +12 +17 +15 +17 +19 +15 +18 +15 +18 +16 +11 +23 +8 +14 +15 +12 +12 +8 +25 +7 +20 +11 +13 +19 +22 +13 +14 +50 +10 +26 +22 +8 +13 +19 +43 +11 +21 +22 +12 +11 +24 +12 +13 +17 +11 +9 +22 +18 +8 +19 +10 +18 +8 +74 +12 +16 +11 +34 +9 +12 +10 +10 +18 +11 +16 +30 +9 +26 +23 +7 +14 +23 +26 +10 +11 +10 +26 +9 +13 +8 +17 +10 +9 +18 +15 +16 +14 +35 +11 +10 +27 +11 +17 +10 +11 +25 +10 +8 +10 +29 +11 +13 +11 +12 +24 +10 +21 +12 +9 +10 +13 +20 +18 +29 +19 +41 +11 +9 +19 +-1 +12 +16 +23 +25 +20 +8 +11 +11 +8 +12 +8 +8 +50 +8 +25 +94 +20 +7 +35 +15 +11 +9 +22 +10 +9 +9 +13 +10 +16 +19 +15 +11 +15 +16 +16 +12 +9 +16 +10 +31 +14 +8 +20 +12 +13 +10 +11 +10 +19 +9 +55 +15 +18 +8 +11 +10 +8 +9 +28 +8 +12 +18 +22 +9 +17 +19 +9 +12 +9 +23 +12 +15 +15 +16 +19 +10 +9 +17 +17 +8 +10 +11 +18 +14 +7 +23 +7 +54 +10 +21 +15 +33 +13 +10 +30 +26 +14 +19 +25 +12 +17 +36 +12 +7 +12 +20 +22 +9 +17 +14 +15 +10 +17 +14 +31 +10 +9 +13 +9 +36 +16 +26 +8 +16 +18 +21 +23 +27 +40 +8 +19 +17 +9 +23 +14 +14 +8 +25 +8 +14 +13 +10 +26 +8 +14 +10 +10 +15 +9 +76 +17 +20 +15 +7 +47 +21 +30 +15 +14 +9 +13 +8 +9 +14 +25 +17 +52 +18 +30 +8 +38 +42 +12 +14 +13 +9 +17 +11 +14 +9 +16 +12 +12 +18 +9 +11 +19 +23 +13 +18 +27 +24 +10 +26 +10 +11 +9 +22 +-1 +10 +9 +10 +11 +8 +17 +14 +21 +16 +10 +10 +11 +14 +14 +17 +9 +17 +13 +9 +9 +21 +18 +9 +19 +16 +13 +51 +10 +13 +10 +13 +18 +11 +17 +8 +11 +8 +11 +9 +9 +11 +7 +12 +16 +11 +15 +35 +12 +8 +27 +14 +12 +21 +33 +16 +7 +12 +17 +11 +8 +20 +21 +24 +8 +11 +13 +24 +10 +54 +8 +31 +10 +7 +15 +10 +14 +10 +9 +66 +22 +31 +26 +11 +12 +14 +8 +35 +17 +16 +11 +8 +11 +16 +22 +15 +11 +13 +12 +10 +17 +8 +14 +18 +11 +16 +10 +13 +12 +27 +15 +21 +8 +8 +18 +18 +28 +9 +7 +16 +30 +23 +18 +15 +8 +8 +7 +15 +12 +19 +12 +24 +17 +14 +17 +14 +17 +17 +11 +10 +9 +10 +16 +16 +13 +15 +14 +14 +40 +7 +9 +11 +13 +24 +11 +9 +23 +9 +13 +21 +12 +23 +19 +12 +10 +8 +8 +25 +11 +10 +10 +9 +19 +8 +35 +25 +22 +9 +15 +15 +10 +8 +32 +18 +15 +18 +10 +12 +12 +7 +10 +21 +18 +10 +10 +9 +16 +13 +13 +14 +14 +17 +9 +12 +10 +14 +22 +10 +34 +14 +13 +8 +14 +14 +8 +23 +18 +22 +38 +13 +32 +9 +10 +23 +7 +32 +16 +15 +23 +8 +7 +10 +49 +10 +10 +14 +13 +9 +25 +16 +24 +16 +17 +13 +15 +15 +20 +28 +15 +9 +23 +8 +16 +41 +16 +31 +18 +26 +10 +21 +8 +7 +12 +9 +13 +18 +67 +11 +10 +16 +19 +15 +12 +19 +16 +14 +28 +23 +9 +12 +10 +22 +16 +9 +19 +22 +12 +12 +10 +15 +12 +19 +8 +14 +27 +13 +23 +15 +14 +14 +9 +-1 +8 +28 +12 +8 +20 +13 +15 +8 +15 +7 +15 +24 +24 +20 +12 +9 +18 +15 +12 +17 +8 +23 +13 +28 +16 +13 +12 +99 +7 +15 +26 +16 +9 +12 +30 +24 +12 +15 +11 +23 +14 +13 +8 +9 +17 +10 +9 +10 +10 +8 +11 +25 +22 +10 +19 +20 +23 +12 +21 +50 +19 +8 +31 +59 +13 +14 +32 +10 +8 +8 +16 +12 +30 +10 +14 +10 +12 +17 +7 +13 +17 +28 +25 +8 +14 +10 +21 +13 +27 +17 +14 +26 +8 +9 +15 +16 +19 +51 +10 +23 +13 +12 +9 +7 +8 +9 +14 +12 +17 +14 +-1 +20 +22 +25 +14 +9 +22 +10 +20 +7 +12 +14 +16 +25 +13 +10 +9 +10 +9 +13 +9 +22 +13 +21 +14 +8 +12 +14 +24 +10 +14 +22 +16 +12 +27 +14 +13 +13 +9 +8 +10 +22 +18 +32 +16 +16 +7 +19 +16 +20 +24 +23 +16 +20 +25 +18 +15 +11 +9 +11 +42 +10 +8 +15 +22 +14 +13 +14 +12 +13 +10 +11 +21 +11 +19 +8 +16 +9 +33 +12 +11 +9 +31 +14 +30 +10 +12 +10 +13 +20 +8 +9 +10 +13 +16 +13 +17 +10 +8 +16 +15 +10 +14 +12 +10 +13 +15 +54 +9 +17 +14 +7 +10 +19 +14 +12 +17 +17 +7 +10 +46 +24 +11 +47 +9 +9 +13 +21 +19 +25 +18 +9 +11 +10 +14 +7 +8 +13 +8 +13 +12 +14 +24 +17 +11 +34 +36 +97 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k7.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k7.txt new file mode 100644 index 0000000..f60a9a6 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k7.txt @@ -0,0 +1,1000 @@ +15 +14 +16 +18 +20 +25 +11 +18 +17 +19 +42 +19 +17 +18 +29 +15 +10 +15 +-1 +17 +22 +23 +66 +37 +19 +17 +23 +24 +31 +23 +21 +14 +52 +26 +12 +14 +20 +21 +20 +25 +-1 +14 +13 +14 +16 +11 +-1 +9 +51 +25 +33 +21 +11 +13 +18 +32 +20 +26 +26 +19 +21 +-1 +16 +39 +14 +19 +16 +19 +17 +17 +-1 +40 +27 +16 +11 +15 +34 +20 +-1 +18 +29 +11 +14 +36 +-1 +29 +19 +15 +44 +14 +29 +13 +15 +21 +23 +18 +21 +13 +24 +16 +34 +13 +17 +13 +17 +-1 +18 +14 +24 +19 +16 +25 +36 +13 +20 +18 +12 +34 +14 +20 +16 +12 +14 +19 +39 +29 +11 +14 +20 +15 +22 +22 +24 +38 +23 +16 +17 +42 +82 +42 +18 +18 +25 +15 +28 +53 +-1 +27 +14 +19 +24 +27 +24 +19 +-1 +22 +17 +34 +-1 +19 +12 +29 +52 +37 +16 +20 +24 +-1 +69 +-1 +35 +13 +26 +19 +39 +20 +33 +15 +18 +34 +15 +20 +15 +19 +15 +20 +15 +15 +17 +21 +47 +12 +19 +22 +16 +16 +-1 +-1 +17 +-1 +51 +19 +36 +14 +11 +18 +58 +18 +26 +52 +34 +14 +16 +17 +16 +31 +16 +29 +12 +11 +14 +78 +29 +11 +24 +-1 +25 +21 +17 +39 +17 +46 +19 +12 +38 +12 +20 +69 +-1 +16 +-1 +20 +20 +19 +12 +11 +-1 +67 +20 +17 +13 +19 +30 +16 +27 +-1 +18 +14 +22 +22 +24 +15 +13 +13 +10 +40 +13 +15 +13 +22 +17 +24 +25 +23 +19 +50 +18 +23 +15 +14 +16 +28 +20 +15 +15 +14 +31 +16 +29 +12 +15 +56 +13 +21 +17 +17 +22 +31 +14 +21 +14 +13 +-1 +22 +31 +-1 +15 +-1 +54 +16 +13 +-1 +-1 +26 +16 +84 +21 +22 +21 +15 +14 +21 +27 +14 +24 +24 +18 +20 +14 +12 +26 +14 +15 +23 +27 +82 +17 +21 +26 +28 +16 +19 +16 +13 +10 +28 +32 +57 +24 +21 +22 +27 +-1 +24 +12 +23 +27 +-1 +18 +50 +22 +57 +24 +17 +36 +22 +14 +-1 +35 +18 +24 +12 +14 +14 +23 +21 +36 +29 +23 +24 +-1 +25 +13 +-1 +11 +14 +13 +-1 +17 +18 +-1 +11 +23 +44 +15 +19 +12 +32 +25 +22 +14 +23 +-1 +20 +47 +17 +21 +14 +-1 +-1 +27 +10 +31 +37 +21 +16 +13 +24 +11 +-1 +20 +9 +15 +26 +15 +11 +15 +11 +13 +-1 +35 +15 +16 +-1 +23 +-1 +15 +19 +19 +12 +19 +14 +23 +23 +38 +12 +16 +17 +17 +24 +34 +22 +22 +17 +24 +19 +12 +13 +16 +15 +16 +18 +54 +34 +14 +29 +12 +64 +70 +17 +13 +23 +11 +15 +15 +42 +24 +73 +16 +16 +24 +10 +21 +28 +24 +48 +23 +30 +16 +-1 +11 +18 +29 +29 +-1 +13 +21 +29 +23 +-1 +24 +24 +16 +13 +-1 +14 +22 +16 +33 +11 +34 +15 +16 +26 +18 +18 +13 +21 +11 +-1 +14 +32 +-1 +29 +19 +25 +19 +15 +26 +16 +27 +16 +26 +10 +38 +-1 +19 +22 +14 +26 +13 +30 +-1 +13 +23 +-1 +26 +19 +36 +23 +33 +-1 +-1 +16 +-1 +11 +9 +17 +-1 +18 +25 +21 +21 +14 +41 +78 +27 +19 +25 +26 +19 +12 +22 +18 +23 +64 +20 +23 +17 +23 +17 +40 +11 +17 +20 +26 +13 +-1 +24 +28 +56 +18 +14 +24 +12 +15 +21 +-1 +-1 +14 +-1 +30 +29 +31 +-1 +25 +14 +25 +79 +12 +14 +16 +-1 +21 +51 +13 +15 +16 +25 +39 +13 +31 +16 +-1 +45 +17 +20 +47 +23 +13 +24 +14 +12 +18 +18 +23 +11 +11 +32 +20 +12 +29 +22 +-1 +19 +21 +18 +48 +22 +28 +27 +34 +15 +16 +28 +36 +13 +32 +36 +-1 +18 +12 +15 +12 +20 +50 +20 +13 +21 +12 +10 +22 +-1 +16 +14 +18 +17 +22 +22 +28 +23 +-1 +-1 +34 +-1 +63 +19 +17 +28 +18 +28 +-1 +-1 +27 +29 +-1 +71 +17 +42 +29 +13 +30 +35 +10 +15 +15 +19 +21 +19 +24 +38 +21 +72 +92 +19 +25 +14 +68 +23 +-1 +19 +18 +12 +18 +31 +20 +12 +14 +12 +-1 +-1 +17 +29 +22 +12 +32 +11 +20 +47 +20 +38 +18 +19 +12 +75 +37 +17 +18 +15 +20 +16 +15 +19 +18 +46 +15 +20 +17 +25 +11 +16 +27 +42 +14 +19 +19 +22 +13 +19 +22 +18 +-1 +14 +17 +18 +20 +14 +18 +-1 +24 +17 +14 +-1 +23 +16 +13 +16 +17 +-1 +28 +28 +17 +46 +-1 +13 +20 +-1 +29 +55 +16 +45 +13 +30 +24 +11 +17 +18 +31 +14 +21 +11 +29 +15 +25 +21 +24 +42 +23 +12 +-1 +18 +13 +14 +-1 +18 +24 +11 +21 +14 +16 +29 +16 +27 +22 +11 +-1 +25 +19 +25 +-1 +19 +12 +21 +16 +12 +17 +33 +12 +-1 +15 +12 +29 +30 +78 +11 +12 +11 +21 +21 +20 +67 +29 +12 +14 +18 +16 +-1 +13 +19 +18 +19 +57 +20 +24 +21 +20 +17 +22 +-1 +-1 +17 +18 +31 +60 +13 +23 +16 +25 +19 +16 +10 +16 +37 +21 +-1 +18 +26 +14 +19 +13 +45 +78 +13 +33 +25 +18 +13 +21 +16 +20 +25 +13 +15 +21 +29 +22 +17 +16 +21 +60 +15 +23 +30 +27 +40 +33 +-1 +42 +18 +17 +22 +20 +14 +25 +26 +-1 +12 +17 +23 +82 +15 +32 +14 +25 +17 +-1 +13 +33 +25 +12 +20 +-1 +20 +15 +37 +18 +15 +20 +15 +17 +11 +36 +17 +42 +21 +26 +22 +18 +13 +14 +14 +18 +21 +14 +-1 +11 +-1 +19 +25 +22 +19 +12 +-1 +19 +29 +20 +16 +21 +14 +14 +-1 +35 +12 +16 +21 +32 +43 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k8.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k8.txt new file mode 100644 index 0000000..02ad689 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k8.txt @@ -0,0 +1,1000 @@ +21 +21 +22 +33 +23 +42 +35 +26 +72 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +93 +64 +-1 +-1 +25 +-1 +-1 +14 +-1 +-1 +17 +-1 +15 +-1 +66 +-1 +-1 +21 +-1 +19 +17 +61 +-1 +-1 +-1 +24 +16 +24 +18 +-1 +26 +-1 +25 +16 +26 +24 +26 +22 +-1 +-1 +-1 +-1 +29 +21 +-1 +28 +22 +45 +52 +-1 +25 +-1 +-1 +24 +-1 +16 +23 +-1 +33 +17 +-1 +16 +-1 +-1 +-1 +17 +-1 +23 +-1 +-1 +49 +25 +41 +-1 +39 +21 +24 +23 +15 +-1 +25 +40 +18 +-1 +-1 +-1 +-1 +-1 +40 +-1 +-1 +-1 +22 +-1 +-1 +24 +-1 +-1 +20 +21 +-1 +-1 +23 +36 +21 +-1 +28 +-1 +24 +-1 +-1 +-1 +28 +-1 +-1 +-1 +34 +-1 +23 +-1 +-1 +-1 +-1 +-1 +38 +32 +-1 +-1 +-1 +22 +34 +-1 +-1 +-1 +-1 +23 +33 +15 +-1 +22 +-1 +30 +-1 +25 +25 +21 +15 +25 +32 +-1 +73 +26 +31 +23 +-1 +-1 +-1 +28 +-1 +18 +-1 +-1 +-1 +40 +50 +13 +-1 +21 +-1 +15 +60 +31 +-1 +24 +22 +-1 +25 +41 +-1 +-1 +22 +-1 +31 +-1 +34 +39 +-1 +-1 +42 +21 +23 +-1 +53 +-1 +-1 +-1 +-1 +26 +-1 +-1 +-1 +-1 +-1 +26 +-1 +-1 +22 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +28 +19 +60 +23 +-1 +31 +30 +-1 +-1 +-1 +-1 +32 +18 +-1 +-1 +-1 +88 +-1 +-1 +46 +15 +20 +-1 +-1 +39 +-1 +-1 +-1 +-1 +18 +61 +30 +-1 +-1 +22 +-1 +-1 +-1 +-1 +17 +-1 +18 +15 +-1 +35 +-1 +-1 +-1 +-1 +32 +23 +-1 +65 +21 +-1 +33 +26 +-1 +-1 +-1 +24 +-1 +-1 +21 +-1 +24 +44 +19 +25 +23 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +42 +-1 +15 +25 +17 +44 +22 +19 +-1 +-1 +-1 +-1 +18 +-1 +-1 +-1 +34 +-1 +15 +26 +-1 +23 +-1 +-1 +-1 +23 +32 +20 +-1 +24 +-1 +20 +-1 +32 +-1 +20 +-1 +20 +-1 +-1 +-1 +31 +43 +-1 +-1 +-1 +40 +-1 +-1 +-1 +-1 +37 +25 +22 +47 +24 +32 +21 +23 +-1 +23 +-1 +-1 +-1 +-1 +-1 +45 +-1 +-1 +33 +-1 +21 +-1 +-1 +-1 +29 +-1 +52 +23 +-1 +24 +-1 +26 +31 +-1 +-1 +36 +38 +24 +-1 +23 +72 +-1 +38 +-1 +14 +51 +20 +-1 +32 +-1 +18 +-1 +14 +-1 +-1 +-1 +-1 +21 +-1 +25 +-1 +21 +27 +14 +26 +20 +-1 +24 +-1 +15 +-1 +-1 +-1 +15 +-1 +26 +-1 +21 +-1 +-1 +31 +19 +-1 +-1 +21 +22 +-1 +-1 +-1 +-1 +28 +21 +26 +23 +-1 +-1 +22 +-1 +30 +28 +-1 +-1 +41 +34 +41 +-1 +17 +26 +16 +16 +24 +27 +48 +15 +-1 +-1 +-1 +-1 +18 +-1 +17 +22 +-1 +-1 +28 +-1 +33 +-1 +-1 +61 +83 +-1 +50 +-1 +46 +-1 +24 +-1 +25 +22 +-1 +87 +-1 +-1 +-1 +18 +-1 +25 +21 +23 +27 +-1 +36 +66 +17 +-1 +83 +-1 +-1 +-1 +22 +-1 +-1 +70 +-1 +32 +18 +-1 +37 +35 +18 +22 +17 +-1 +-1 +40 +37 +-1 +-1 +22 +15 +-1 +-1 +15 +26 +-1 +44 +23 +24 +30 +-1 +25 +48 +-1 +-1 +-1 +-1 +47 +-1 +24 +-1 +15 +-1 +19 +27 +-1 +-1 +39 +22 +32 +-1 +-1 +23 +21 +-1 +41 +32 +-1 +24 +-1 +-1 +21 +48 +-1 +-1 +-1 +45 +17 +31 +-1 +44 +-1 +-1 +-1 +26 +23 +26 +31 +-1 +-1 +-1 +27 +-1 +31 +-1 +-1 +-1 +-1 +42 +-1 +-1 +27 +-1 +-1 +23 +-1 +-1 +27 +-1 +19 +18 +-1 +29 +-1 +-1 +40 +93 +59 +28 +47 +42 +18 +-1 +-1 +-1 +22 +-1 +32 +20 +-1 +44 +17 +17 +-1 +-1 +-1 +-1 +-1 +-1 +33 +-1 +-1 +29 +-1 +-1 +-1 +25 +25 +28 +-1 +71 +51 +14 +-1 +-1 +-1 +-1 +-1 +-1 +34 +22 +36 +34 +-1 +-1 +-1 +21 +23 +20 +16 +-1 +-1 +-1 +25 +-1 +-1 +24 +28 +-1 +-1 +-1 +17 +-1 +-1 +66 +-1 +16 +19 +-1 +24 +15 +46 +21 +16 +-1 +-1 +-1 +-1 +-1 +-1 +14 +15 +15 +-1 +-1 +-1 +-1 +14 +30 +-1 +-1 +-1 +-1 +86 +26 +35 +29 +29 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +14 +-1 +-1 +21 +-1 +32 +-1 +-1 +14 +-1 +43 +-1 +-1 +52 +26 +22 +-1 +-1 +34 +30 +54 +-1 +-1 +-1 +22 +-1 +-1 +-1 +-1 +17 +24 +15 +-1 +18 +23 +61 +26 +20 +-1 +20 +71 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +21 +-1 +18 +30 +-1 +-1 +24 +26 +42 +-1 +-1 +27 +24 +-1 +27 +-1 +-1 +24 +40 +77 +28 +-1 +18 +-1 +-1 +-1 +22 +-1 +-1 +26 +24 +-1 +25 +-1 +38 +-1 +-1 +16 +-1 +-1 +24 +-1 +-1 +-1 +-1 +-1 +41 +-1 +-1 +-1 +19 +19 +-1 +-1 +-1 +-1 +28 +-1 +-1 +27 +-1 +-1 +35 +36 +35 +-1 +-1 +17 +-1 +-1 +-1 +16 +-1 +-1 +73 +26 +-1 +-1 +20 +42 +-1 +-1 +17 +-1 +51 +34 +27 +-1 +-1 +-1 +21 +37 +-1 +-1 +20 +25 +54 +25 +14 +26 +47 +-1 +19 +32 +25 +-1 +26 +-1 +37 +54 +-1 +-1 +25 +34 +23 +-1 +22 +29 +-1 +-1 +34 +-1 +53 +24 +30 +29 +23 +21 +-1 +49 +-1 +-1 +-1 +20 +-1 +-1 +-1 +57 +33 +49 +19 +20 +23 +31 +26 +-1 +20 +-1 +-1 +-1 +22 +31 +28 +-1 +-1 +-1 +-1 +26 +-1 +-1 +40 +22 +39 +-1 +86 +-1 +-1 +-1 +-1 +-1 +20 +-1 +28 +22 +-1 +33 +27 +31 +-1 +21 +-1 +23 +-1 +22 +-1 +36 +22 +33 +-1 +31 +-1 +16 +32 +-1 +-1 +-1 +23 +-1 +26 +-1 +-1 +-1 +-1 +26 +-1 +49 +-1 +22 +-1 +20 +-1 +16 +-1 +29 +24 +-1 +34 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k8_different_grid_sizes.txt new file mode 100644 index 0000000..30b824a --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +18 +17 +28 +-1 +24 +-1 +-1 +-1 +28 +-1 +33 +-1 +-1 +31 +-1 +-1 +30 +24 +32 +17 +14 +-1 +24 +-1 +31 +21 +29 +-1 +-1 +14 +39 +-1 +-1 +-1 +-1 +-1 +20 +32 +-1 +23 +25 +-1 +-1 +-1 +-1 +25 +-1 +-1 +23 +26 +-1 +-1 +20 +32 +22 +22 +-1 +-1 +48 +-1 +21 +34 +-1 +25 +-1 +-1 +-1 +23 +-1 +36 +33 +23 +-1 +20 +15 +30 +-1 +-1 +31 +-1 +-1 +-1 +-1 +-1 +-1 +15 +21 +21 +-1 +57 +20 +-1 +-1 +-1 +58 +-1 +34 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k9.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k9.txt new file mode 100644 index 0000000..4e77b5d --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_2x2_k9.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +56 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +46 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +33 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +27 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +48 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +29 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +50 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +70 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +40 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +27 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +45 +-1 +-1 +-1 +-1 +-1 +34 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +41 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +31 +-1 +-1 +-1 +-1 +-1 +53 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +24 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +30 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +42 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +41 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +30 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +54 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +20 +-1 +-1 +41 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +40 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +45 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +40 +-1 +-1 +22 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +29 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +24 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +25 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_3x3_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_3x3_k8_different_grid_sizes.txt new file mode 100644 index 0000000..3d80f4a --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_3x3_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +16 +34 +34 +59 +62 +25 +94 +75 +27 +-1 +30 +100 +-1 +50 +60 +73 +76 +-1 +-1 +29 +88 +-1 +84 +65 +37 +-1 +63 +24 +56 +80 +74 +-1 +29 +64 +-1 +47 +-1 +24 +16 +64 +-1 +-1 +-1 +39 +55 +-1 +60 +31 +79 +86 +-1 +85 +60 +58 +68 +71 +-1 +52 +15 +63 +46 +-1 +-1 +-1 +58 +-1 +-1 +47 +-1 +-1 +48 +-1 +-1 +-1 +57 +94 +-1 +100 +-1 +41 +67 +-1 +-1 +66 +34 +-1 +36 +-1 +20 +48 +-1 +26 +-1 +58 +83 +91 +70 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_4x4_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_4x4_k8_different_grid_sizes.txt new file mode 100644 index 0000000..3359bf2 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_4x4_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +27 +44 +43 +49 +60 +-1 +-1 +-1 +65 +-1 +-1 +-1 +54 +-1 +23 +51 +40 +69 +49 +69 +-1 +-1 +83 +36 +-1 +52 +-1 +-1 +-1 +75 +46 +-1 +-1 +68 +58 +-1 +53 +-1 +-1 +-1 +66 +77 +27 +-1 +95 +-1 +71 +37 +-1 +-1 +-1 +-1 +23 +-1 +-1 +82 +-1 +37 +-1 +70 +20 +33 +-1 +-1 +64 +-1 +34 +29 +66 +47 +-1 +-1 +80 +-1 +-1 +-1 +16 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +50 +96 +-1 +40 +55 +61 +-1 +-1 +82 +92 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k10.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k10.txt new file mode 100644 index 0000000..8e94a7a --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k10.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +39 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +77 +-1 +97 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +97 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +69 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +88 +89 +-1 +-1 +81 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +66 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +68 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +93 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +88 +-1 +-1 +-1 +97 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +76 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +87 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +68 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +78 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +87 +-1 +-1 +-1 +-1 +-1 +-1 +71 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +81 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +99 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +71 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +76 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +65 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +93 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k11.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k11.txt new file mode 100644 index 0000000..03f3f2a --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k11.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +98 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k12.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k12.txt new file mode 100644 index 0000000..033cb5b --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k12.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k13.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k13.txt new file mode 100644 index 0000000..033cb5b --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k13.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k5.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k5.txt new file mode 100644 index 0000000..67ddc56 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k5.txt @@ -0,0 +1,1000 @@ +7 +11 +4 +11 +13 +5 +3 +22 +18 +30 +3 +3 +3 +3 +3 +3 +15 +33 +16 +18 +3 +15 +7 +3 +74 +4 +8 +-1 +37 +37 +16 +10 +41 +36 +3 +3 +6 +12 +8 +47 +5 +4 +3 +72 +8 +3 +6 +3 +37 +16 +3 +19 +15 +19 +8 +3 +28 +22 +10 +37 +5 +27 +12 +5 +3 +3 +3 +3 +3 +18 +17 +32 +3 +3 +3 +9 +14 +3 +5 +19 +3 +14 +29 +9 +-1 +16 +6 +3 +92 +11 +27 +36 +9 +3 +5 +4 +3 +15 +12 +12 +3 +-1 +3 +20 +10 +5 +22 +19 +3 +16 +25 +6 +54 +3 +10 +3 +4 +3 +4 +3 +6 +3 +3 +21 +31 +21 +18 +6 +69 +11 +3 +3 +78 +9 +63 +12 +14 +4 +4 +6 +6 +3 +-1 +16 +9 +16 +3 +3 +3 +3 +21 +3 +4 +8 +3 +11 +3 +95 +3 +3 +6 +4 +9 +-1 +3 +3 +3 +4 +10 +27 +4 +3 +8 +21 +3 +3 +9 +5 +2 +8 +3 +3 +12 +3 +32 +22 +18 +3 +13 +3 +5 +10 +4 +5 +3 +16 +14 +17 +14 +3 +11 +21 +12 +77 +8 +8 +19 +15 +11 +12 +3 +3 +4 +12 +12 +44 +60 +5 +12 +12 +17 +3 +3 +3 +56 +3 +3 +31 +45 +19 +3 +12 +32 +11 +3 +39 +5 +10 +11 +7 +3 +16 +3 +3 +9 +3 +3 +3 +6 +16 +6 +8 +43 +6 +3 +15 +3 +3 +66 +4 +16 +41 +18 +7 +16 +3 +9 +3 +3 +12 +66 +13 +2 +3 +3 +23 +24 +26 +50 +10 +18 +19 +29 +6 +11 +3 +20 +5 +21 +10 +7 +5 +3 +-1 +2 +-1 +7 +20 +3 +3 +3 +6 +22 +3 +4 +3 +14 +32 +3 +11 +4 +3 +12 +35 +10 +11 +3 +28 +8 +4 +3 +18 +6 +12 +11 +24 +3 +25 +3 +24 +3 +3 +19 +9 +15 +5 +39 +3 +3 +3 +12 +4 +3 +3 +5 +3 +26 +11 +15 +25 +3 +15 +2 +3 +10 +5 +71 +55 +25 +8 +4 +6 +26 +18 +41 +3 +3 +97 +3 +26 +13 +3 +13 +3 +15 +10 +43 +18 +6 +3 +31 +9 +19 +17 +21 +3 +20 +22 +3 +39 +21 +7 +14 +3 +30 +16 +9 +24 +16 +49 +16 +27 +4 +3 +3 +2 +9 +3 +3 +13 +12 +5 +6 +11 +6 +41 +17 +25 +21 +3 +10 +3 +5 +29 +39 +12 +3 +44 +16 +13 +3 +2 +3 +88 +-1 +8 +22 +5 +15 +84 +18 +19 +6 +3 +3 +21 +3 +80 +13 +4 +6 +3 +28 +3 +36 +11 +13 +3 +3 +8 +7 +15 +14 +3 +58 +20 +5 +11 +25 +3 +3 +13 +14 +10 +5 +5 +6 +3 +3 +11 +3 +3 +8 +33 +4 +18 +11 +16 +14 +3 +3 +10 +3 +3 +30 +69 +35 +3 +25 +13 +3 +15 +13 +5 +3 +3 +3 +37 +-1 +16 +14 +55 +3 +3 +5 +21 +15 +34 +3 +3 +3 +3 +5 +65 +-1 +3 +22 +48 +22 +4 +13 +18 +9 +19 +97 +3 +5 +3 +3 +11 +7 +4 +3 +18 +8 +48 +20 +6 +23 +15 +10 +24 +25 +10 +70 +16 +9 +9 +3 +3 +49 +3 +8 +3 +68 +3 +14 +3 +3 +5 +3 +3 +3 +27 +13 +3 +3 +4 +17 +3 +3 +4 +32 +3 +21 +3 +17 +20 +10 +37 +23 +3 +3 +5 +3 +3 +3 +11 +4 +12 +3 +12 +62 +9 +20 +34 +3 +6 +20 +15 +3 +30 +3 +21 +17 +9 +21 +18 +17 +13 +20 +3 +34 +9 +3 +16 +18 +16 +12 +3 +3 +56 +41 +11 +3 +12 +24 +27 +13 +5 +57 +8 +5 +70 +9 +12 +23 +5 +3 +9 +10 +14 +24 +17 +3 +4 +8 +4 +3 +21 +35 +3 +19 +5 +36 +3 +3 +25 +70 +3 +3 +23 +71 +26 +3 +16 +57 +3 +16 +11 +4 +3 +12 +16 +3 +26 +3 +38 +31 +17 +3 +2 +40 +3 +43 +26 +3 +9 +4 +39 +8 +19 +3 +3 +15 +5 +8 +3 +5 +3 +23 +3 +59 +12 +10 +3 +3 +10 +12 +16 +3 +16 +6 +3 +3 +3 +6 +3 +3 +13 +13 +11 +14 +62 +3 +28 +51 +3 +13 +21 +3 +13 +3 +10 +12 +3 +11 +3 +27 +5 +9 +3 +19 +3 +26 +23 +6 +3 +13 +2 +11 +3 +4 +44 +7 +17 +12 +3 +12 +2 +33 +8 +11 +32 +36 +22 +6 +11 +3 +5 +13 +3 +3 +14 +15 +10 +3 +3 +16 +3 +3 +61 +11 +3 +14 +9 +9 +3 +7 +3 +7 +8 +11 +11 +39 +100 +-1 +14 +30 +6 +48 +64 +3 +3 +17 +5 +15 +3 +11 +3 +3 +12 +11 +3 +38 +3 +3 +35 +8 +-1 +31 +3 +3 +11 +35 +10 +3 +3 +3 +9 +3 +18 +59 +6 +17 +6 +3 +-1 +11 +9 +22 +-1 +73 +20 +39 +49 +15 +4 +19 +63 +21 +35 +3 +6 +10 +3 +3 +8 +3 +10 +18 +-1 +24 +4 +4 +3 +15 +49 +14 +3 +3 +57 +3 +6 +3 +3 +4 +6 +33 +47 +44 +3 +8 +21 +4 +3 +3 +45 +6 +30 +3 +8 +3 +13 +20 +4 +57 +3 +5 +3 +10 +3 +-1 +21 +3 +5 +-1 +5 +31 +3 +7 +14 +3 +3 +32 +8 +33 +49 +15 +3 +3 +3 +3 +10 +87 +17 +3 +7 +10 +4 +3 +47 +23 +3 +4 +3 +12 +18 +6 +3 +5 +3 +-1 +3 +65 +3 +29 +3 +3 +3 +3 +3 +22 +37 +20 +18 +7 +15 +-1 +5 +21 +3 +17 +3 +7 +2 +21 +28 +16 +6 +8 +28 +3 +5 +4 +5 +3 +3 +9 +3 +11 +13 +9 +61 +39 +10 +15 +66 +14 +54 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k6.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k6.txt new file mode 100644 index 0000000..28b9936 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k6.txt @@ -0,0 +1,1000 @@ +6 +10 +17 +13 +16 +6 +25 +12 +8 +22 +10 +8 +24 +8 +7 +10 +48 +9 +17 +8 +52 +32 +57 +9 +22 +75 +71 +15 +13 +15 +84 +25 +9 +8 +12 +38 +41 +84 +16 +17 +52 +9 +53 +82 +33 +30 +9 +61 +31 +-1 +24 +48 +9 +31 +9 +10 +73 +58 +-1 +38 +8 +7 +53 +26 +8 +27 +9 +-1 +74 +33 +9 +8 +-1 +-1 +13 +9 +90 +12 +13 +40 +12 +39 +21 +9 +9 +67 +11 +22 +20 +23 +27 +9 +12 +35 +68 +45 +11 +18 +28 +34 +23 +11 +49 +50 +21 +15 +8 +35 +77 +17 +13 +9 +25 +8 +21 +11 +-1 +8 +8 +10 +-1 +12 +9 +12 +10 +23 +18 +10 +36 +57 +-1 +23 +24 +42 +70 +23 +11 +37 +15 +-1 +-1 +25 +11 +10 +12 +53 +9 +11 +39 +45 +-1 +9 +12 +47 +24 +26 +25 +20 +30 +40 +12 +8 +39 +-1 +9 +36 +-1 +15 +24 +40 +8 +69 +13 +12 +10 +11 +13 +17 +-1 +38 +73 +32 +-1 +9 +-1 +13 +55 +39 +9 +14 +12 +45 +13 +18 +11 +10 +31 +10 +14 +24 +9 +12 +-1 +-1 +9 +31 +34 +46 +27 +43 +22 +9 +26 +8 +-1 +17 +26 +56 +39 +11 +-1 +60 +42 +18 +17 +7 +78 +38 +22 +8 +59 +13 +12 +42 +13 +42 +13 +69 +-1 +55 +7 +37 +-1 +-1 +41 +8 +10 +33 +46 +-1 +56 +12 +8 +20 +9 +39 +29 +-1 +18 +42 +37 +17 +13 +27 +9 +30 +34 +25 +86 +13 +10 +9 +29 +13 +10 +20 +12 +62 +38 +9 +19 +9 +19 +22 +25 +22 +12 +8 +9 +-1 +67 +12 +10 +24 +13 +54 +20 +23 +-1 +20 +71 +37 +30 +11 +11 +52 +10 +99 +10 +8 +19 +11 +10 +24 +50 +14 +-1 +19 +49 +24 +9 +14 +15 +50 +7 +30 +15 +9 +18 +8 +15 +21 +41 +18 +47 +65 +57 +21 +12 +14 +79 +13 +50 +10 +10 +14 +28 +22 +13 +18 +9 +7 +30 +31 +16 +-1 +63 +34 +81 +18 +8 +9 +70 +9 +34 +64 +56 +14 +-1 +13 +94 +-1 +-1 +9 +33 +7 +25 +52 +26 +35 +15 +38 +38 +11 +41 +84 +55 +65 +14 +8 +12 +38 +9 +17 +78 +11 +11 +-1 +24 +16 +18 +58 +10 +60 +69 +73 +9 +33 +16 +73 +23 +30 +14 +17 +11 +19 +11 +13 +11 +20 +58 +11 +83 +28 +19 +19 +28 +-1 +-1 +13 +60 +25 +17 +58 +45 +-1 +-1 +46 +43 +9 +23 +8 +31 +36 +27 +-1 +30 +7 +70 +8 +10 +20 +15 +31 +11 +68 +-1 +19 +9 +17 +59 +41 +12 +11 +10 +17 +36 +11 +10 +16 +8 +22 +33 +74 +46 +-1 +17 +-1 +15 +43 +17 +48 +27 +14 +14 +8 +9 +12 +37 +-1 +11 +-1 +57 +40 +27 +58 +12 +22 +16 +47 +9 +29 +28 +32 +9 +9 +10 +32 +11 +-1 +46 +67 +80 +22 +26 +8 +98 +7 +71 +9 +24 +24 +30 +76 +49 +9 +55 +9 +29 +-1 +11 +25 +-1 +65 +13 +33 +17 +11 +37 +46 +21 +83 +11 +27 +81 +22 +16 +14 +45 +78 +18 +16 +22 +32 +10 +-1 +40 +8 +23 +70 +34 +13 +59 +21 +-1 +25 +63 +48 +12 +61 +18 +-1 +91 +9 +66 +20 +9 +-1 +10 +8 +40 +94 +7 +32 +42 +-1 +9 +12 +56 +15 +9 +24 +-1 +10 +63 +47 +28 +-1 +27 +12 +-1 +-1 +10 +20 +20 +65 +11 +-1 +-1 +-1 +19 +14 +16 +12 +-1 +20 +12 +38 +11 +14 +66 +12 +96 +7 +11 +-1 +50 +19 +37 +22 +8 +13 +26 +21 +11 +14 +9 +-1 +11 +-1 +10 +28 +43 +9 +9 +22 +12 +-1 +-1 +63 +10 +8 +22 +39 +9 +14 +18 +25 +63 +42 +11 +38 +13 +56 +37 +22 +10 +19 +32 +11 +12 +91 +8 +71 +42 +15 +19 +20 +52 +-1 +10 +10 +14 +9 +9 +-1 +10 +48 +-1 +19 +75 +25 +46 +9 +40 +18 +18 +13 +44 +51 +11 +25 +12 +51 +10 +36 +29 +12 +-1 +13 +23 +22 +-1 +-1 +22 +12 +54 +10 +10 +9 +28 +49 +36 +14 +9 +9 +44 +8 +53 +31 +20 +15 +33 +15 +77 +66 +21 +27 +11 +46 +17 +-1 +-1 +76 +15 +25 +13 +18 +9 +8 +31 +14 +46 +15 +41 +16 +35 +-1 +19 +16 +14 +9 +23 +12 +25 +12 +35 +26 +14 +76 +11 +9 +63 +17 +13 +19 +19 +7 +11 +31 +27 +52 +9 +31 +27 +16 +11 +57 +11 +51 +35 +12 +13 +18 +-1 +16 +9 +16 +37 +8 +52 +11 +40 +19 +10 +28 +10 +84 +18 +8 +27 +94 +38 +-1 +26 +-1 +26 +12 +22 +59 +-1 +-1 +9 +77 +24 +36 +7 +42 +9 +29 +23 +17 +28 +15 +19 +-1 +52 +10 +20 +10 +11 +53 +-1 +10 +11 +24 +8 +8 +8 +25 +22 +25 +12 +13 +85 +15 +11 +66 +12 +36 +64 +31 +8 +67 +29 +80 +10 +8 +28 +10 +41 +14 +21 +64 +14 +59 +8 +59 +-1 +35 +7 +8 +17 +12 +22 +13 +17 +12 +17 +57 +25 +53 +7 +16 +18 +98 +61 +8 +12 +20 +46 +11 +23 +11 +30 +20 +-1 +34 +13 +-1 +10 +10 +15 +10 +33 +19 +8 +70 +23 +45 +68 +9 +15 +-1 +20 +31 +8 +30 +18 +37 +17 +9 +24 +9 +12 +34 +19 +19 +12 +-1 +46 +13 +10 +14 +10 +52 +-1 +10 +67 +8 +40 +72 +49 +-1 +41 +17 +42 +-1 +25 +-1 +50 +37 +9 +44 +28 +17 +24 +29 +12 +66 +60 +29 +10 +17 +10 +25 +18 +9 +70 +-1 +53 +14 +16 +8 +9 +26 +22 +21 +55 +9 +16 +-1 +21 +18 +-1 +37 +-1 +58 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k7.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k7.txt new file mode 100644 index 0000000..69c29ee --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k7.txt @@ -0,0 +1,1000 @@ +13 +19 +19 +22 +26 +13 +37 +43 +28 +43 +27 +72 +-1 +86 +-1 +-1 +-1 +-1 +85 +31 +73 +37 +31 +56 +-1 +-1 +-1 +16 +66 +88 +-1 +16 +-1 +22 +20 +-1 +98 +-1 +26 +63 +17 +-1 +49 +-1 +-1 +13 +-1 +17 +62 +16 +50 +23 +27 +28 +60 +26 +-1 +27 +70 +12 +23 +-1 +19 +55 +29 +21 +87 +45 +13 +14 +-1 +-1 +44 +34 +76 +25 +47 +-1 +36 +66 +24 +-1 +69 +-1 +19 +92 +32 +17 +-1 +10 +-1 +13 +15 +17 +-1 +27 +20 +-1 +24 +87 +37 +47 +-1 +-1 +25 +18 +20 +-1 +80 +64 +45 +28 +55 +27 +-1 +-1 +16 +-1 +43 +32 +19 +46 +-1 +52 +22 +19 +65 +47 +-1 +-1 +24 +-1 +13 +11 +44 +32 +11 +39 +28 +25 +42 +9 +-1 +46 +78 +-1 +-1 +38 +-1 +-1 +18 +29 +59 +51 +31 +18 +83 +13 +94 +11 +79 +43 +12 +22 +42 +42 +-1 +-1 +-1 +22 +-1 +-1 +24 +-1 +36 +16 +65 +29 +31 +-1 +21 +-1 +15 +27 +22 +57 +44 +-1 +-1 +45 +21 +-1 +-1 +30 +-1 +87 +14 +-1 +-1 +44 +76 +38 +-1 +-1 +73 +63 +22 +13 +-1 +-1 +31 +19 +37 +33 +12 +18 +14 +86 +12 +-1 +-1 +38 +-1 +-1 +51 +92 +11 +39 +52 +47 +33 +23 +59 +68 +24 +48 +-1 +-1 +21 +-1 +-1 +47 +37 +22 +-1 +58 +-1 +19 +26 +41 +93 +71 +-1 +-1 +17 +11 +28 +-1 +26 +16 +-1 +16 +29 +-1 +72 +32 +33 +86 +27 +36 +-1 +-1 +-1 +-1 +15 +39 +-1 +14 +55 +12 +-1 +36 +32 +-1 +32 +-1 +-1 +24 +17 +53 +26 +95 +23 +24 +66 +79 +-1 +94 +33 +-1 +31 +26 +36 +-1 +89 +17 +12 +58 +53 +24 +-1 +18 +26 +-1 +54 +34 +10 +24 +-1 +17 +52 +58 +19 +18 +86 +95 +-1 +-1 +70 +59 +-1 +22 +93 +26 +34 +-1 +55 +-1 +24 +19 +33 +-1 +30 +-1 +-1 +17 +-1 +78 +-1 +-1 +61 +75 +28 +22 +-1 +-1 +19 +12 +27 +80 +22 +11 +-1 +71 +22 +-1 +-1 +55 +-1 +14 +17 +-1 +13 +92 +39 +-1 +37 +72 +84 +-1 +38 +15 +47 +-1 +-1 +18 +24 +-1 +86 +82 +84 +-1 +-1 +-1 +65 +66 +-1 +22 +15 +13 +64 +-1 +61 +-1 +12 +28 +73 +12 +-1 +21 +53 +52 +-1 +22 +44 +17 +23 +13 +63 +27 +45 +66 +81 +-1 +-1 +38 +-1 +-1 +-1 +-1 +50 +9 +23 +36 +43 +-1 +-1 +-1 +-1 +14 +14 +21 +-1 +-1 +-1 +37 +44 +20 +-1 +61 +45 +-1 +10 +-1 +41 +30 +-1 +-1 +16 +40 +62 +16 +15 +29 +-1 +-1 +37 +25 +29 +29 +39 +22 +-1 +27 +95 +87 +44 +-1 +-1 +-1 +-1 +64 +44 +97 +33 +58 +34 +51 +36 +-1 +15 +16 +21 +18 +82 +-1 +57 +40 +36 +-1 +55 +45 +52 +-1 +-1 +-1 +18 +-1 +-1 +69 +14 +-1 +-1 +-1 +36 +25 +27 +45 +33 +-1 +97 +55 +22 +32 +-1 +-1 +58 +-1 +59 +45 +69 +13 +40 +21 +-1 +-1 +40 +24 +-1 +26 +72 +96 +-1 +-1 +16 +-1 +-1 +57 +21 +-1 +-1 +90 +23 +-1 +31 +13 +34 +63 +39 +29 +-1 +71 +27 +37 +41 +51 +36 +23 +24 +23 +13 +22 +-1 +37 +-1 +18 +75 +17 +-1 +67 +46 +-1 +66 +15 +19 +-1 +13 +32 +15 +-1 +38 +-1 +84 +11 +-1 +93 +24 +11 +-1 +35 +-1 +-1 +-1 +30 +19 +12 +38 +-1 +-1 +-1 +26 +9 +19 +64 +33 +19 +22 +38 +-1 +62 +71 +82 +41 +31 +49 +-1 +48 +43 +46 +28 +-1 +65 +-1 +-1 +84 +-1 +44 +71 +-1 +51 +-1 +10 +32 +-1 +27 +11 +-1 +-1 +-1 +27 +75 +-1 +11 +18 +16 +26 +14 +-1 +10 +36 +-1 +68 +-1 +24 +15 +25 +15 +25 +31 +50 +-1 +-1 +-1 +-1 +29 +51 +-1 +94 +-1 +57 +-1 +55 +-1 +14 +-1 +-1 +60 +-1 +90 +15 +-1 +30 +98 +41 +34 +-1 +49 +-1 +21 +-1 +24 +-1 +19 +17 +10 +23 +-1 +-1 +73 +-1 +30 +96 +90 +50 +33 +90 +43 +-1 +-1 +-1 +11 +-1 +15 +60 +44 +12 +-1 +-1 +13 +32 +-1 +26 +24 +-1 +15 +19 +73 +17 +-1 +55 +-1 +73 +-1 +19 +-1 +-1 +62 +-1 +62 +12 +38 +69 +-1 +48 +42 +70 +77 +-1 +73 +77 +79 +47 +-1 +-1 +94 +-1 +82 +19 +25 +21 +31 +11 +43 +71 +24 +26 +-1 +12 +-1 +71 +-1 +11 +18 +26 +18 +-1 +58 +13 +14 +13 +23 +18 +-1 +-1 +20 +-1 +36 +16 +11 +44 +62 +-1 +34 +12 +-1 +47 +68 +14 +60 +20 +-1 +29 +28 +16 +50 +39 +-1 +19 +34 +-1 +19 +59 +38 +-1 +18 +13 +-1 +-1 +43 +49 +29 +-1 +27 +13 +-1 +35 +30 +11 +57 +51 +-1 +21 +31 +38 +-1 +17 +20 +33 +96 +74 +52 +18 +21 +82 +-1 +19 +-1 +39 +-1 +11 +28 +-1 +-1 +-1 +16 +-1 +52 +-1 +20 +34 +56 +52 +18 +28 +33 +13 +56 +-1 +11 +-1 +10 +27 +21 +21 +-1 +49 +-1 +25 +20 +28 +84 +71 +86 +-1 +-1 +46 +10 +-1 +-1 +25 +29 +19 +49 +-1 +-1 +32 +-1 +-1 +33 +20 +55 +15 +-1 +67 +99 +65 +-1 +-1 +85 +19 +10 +30 +61 +-1 +61 +20 +82 +11 +-1 +-1 +-1 +-1 +-1 +53 +72 +-1 +-1 +28 +-1 +78 +27 +68 +49 +-1 +82 +57 +59 +17 +11 +-1 +-1 +57 +45 +53 +11 +19 +50 +99 +-1 +26 +81 +16 +52 +-1 +25 +-1 +12 +-1 +-1 +43 +28 +41 +46 +93 +39 +60 +73 +-1 +-1 +75 +-1 +29 +27 +54 +28 +39 +-1 +23 +28 +73 +-1 +-1 +39 +13 +-1 +77 +91 +100 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k8.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k8.txt new file mode 100644 index 0000000..06a1bc4 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k8.txt @@ -0,0 +1,1000 @@ +15 +45 +71 +-1 +16 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +87 +-1 +-1 +-1 +-1 +89 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +82 +-1 +26 +-1 +25 +20 +-1 +79 +-1 +15 +61 +42 +81 +56 +-1 +20 +-1 +42 +-1 +46 +27 +60 +-1 +69 +-1 +79 +22 +-1 +-1 +-1 +-1 +89 +41 +40 +22 +99 +-1 +-1 +82 +-1 +-1 +-1 +74 +-1 +-1 +-1 +52 +52 +52 +-1 +-1 +29 +37 +89 +-1 +87 +-1 +-1 +-1 +-1 +17 +29 +-1 +87 +-1 +21 +-1 +36 +52 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +95 +62 +72 +51 +-1 +-1 +80 +-1 +-1 +-1 +14 +-1 +-1 +31 +-1 +40 +-1 +96 +-1 +-1 +83 +26 +-1 +-1 +84 +-1 +60 +-1 +85 +-1 +-1 +-1 +-1 +30 +-1 +-1 +-1 +-1 +21 +43 +-1 +-1 +61 +59 +96 +39 +-1 +43 +28 +-1 +-1 +-1 +31 +-1 +-1 +68 +61 +83 +-1 +-1 +44 +-1 +16 +-1 +-1 +-1 +-1 +45 +-1 +-1 +94 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +94 +57 +-1 +-1 +14 +-1 +-1 +44 +-1 +-1 +-1 +24 +28 +-1 +40 +-1 +-1 +84 +-1 +-1 +-1 +96 +34 +51 +-1 +65 +-1 +26 +49 +-1 +-1 +-1 +51 +-1 +-1 +-1 +-1 +-1 +-1 +99 +-1 +-1 +-1 +38 +30 +-1 +-1 +-1 +-1 +85 +60 +35 +-1 +-1 +-1 +-1 +32 +-1 +-1 +-1 +35 +-1 +49 +57 +-1 +67 +-1 +64 +-1 +-1 +-1 +-1 +-1 +63 +56 +63 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +34 +91 +97 +-1 +-1 +-1 +-1 +34 +60 +-1 +35 +-1 +59 +-1 +-1 +-1 +-1 +-1 +-1 +74 +-1 +-1 +-1 +49 +28 +44 +-1 +20 +-1 +88 +-1 +17 +36 +75 +-1 +-1 +70 +-1 +-1 +-1 +74 +-1 +48 +-1 +-1 +-1 +-1 +15 +-1 +24 +-1 +-1 +48 +43 +64 +74 +-1 +-1 +93 +-1 +-1 +-1 +64 +60 +28 +28 +39 +48 +-1 +-1 +-1 +37 +-1 +94 +52 +52 +-1 +-1 +-1 +-1 +61 +25 +79 +-1 +-1 +97 +-1 +-1 +-1 +41 +-1 +56 +-1 +88 +-1 +-1 +81 +76 +-1 +-1 +64 +94 +-1 +18 +-1 +-1 +-1 +64 +44 +95 +-1 +75 +85 +37 +79 +-1 +-1 +93 +62 +-1 +-1 +-1 +-1 +-1 +-1 +71 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +39 +43 +-1 +67 +46 +-1 +34 +14 +-1 +87 +-1 +-1 +92 +-1 +-1 +-1 +67 +-1 +-1 +63 +-1 +-1 +-1 +71 +20 +49 +-1 +-1 +53 +78 +16 +-1 +27 +92 +-1 +-1 +-1 +-1 +62 +66 +-1 +49 +18 +-1 +44 +92 +-1 +41 +-1 +-1 +-1 +23 +-1 +30 +77 +-1 +23 +49 +-1 +-1 +14 +-1 +-1 +-1 +23 +-1 +-1 +97 +36 +68 +-1 +71 +-1 +49 +-1 +-1 +-1 +-1 +-1 +50 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +70 +-1 +88 +49 +-1 +-1 +92 +78 +55 +28 +77 +47 +-1 +44 +-1 +61 +-1 +83 +79 +-1 +-1 +-1 +-1 +48 +-1 +36 +77 +91 +-1 +-1 +28 +-1 +-1 +57 +-1 +35 +-1 +44 +65 +91 +42 +28 +51 +-1 +-1 +83 +80 +44 +32 +-1 +-1 +-1 +92 +52 +49 +-1 +-1 +19 +-1 +-1 +52 +59 +-1 +79 +-1 +-1 +-1 +-1 +90 +-1 +53 +18 +-1 +21 +-1 +-1 +49 +100 +-1 +-1 +-1 +-1 +96 +48 +-1 +95 +-1 +-1 +-1 +39 +-1 +89 +-1 +21 +73 +-1 +14 +29 +-1 +36 +-1 +-1 +-1 +15 +-1 +-1 +61 +27 +-1 +85 +-1 +-1 +-1 +36 +59 +-1 +94 +23 +31 +34 +-1 +-1 +-1 +-1 +-1 +96 +-1 +-1 +66 +37 +40 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +18 +-1 +-1 +100 +36 +-1 +-1 +-1 +-1 +43 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +97 +42 +25 +-1 +16 +-1 +-1 +-1 +-1 +59 +-1 +-1 +-1 +-1 +-1 +15 +48 +-1 +56 +22 +-1 +87 +-1 +-1 +-1 +-1 +29 +-1 +-1 +-1 +63 +-1 +-1 +-1 +43 +-1 +64 +51 +-1 +100 +-1 +60 +-1 +33 +65 +52 +-1 +-1 +62 +62 +-1 +21 +-1 +58 +41 +41 +-1 +-1 +43 +-1 +48 +68 +97 +49 +-1 +40 +-1 +-1 +28 +-1 +17 +-1 +-1 +-1 +21 +-1 +-1 +-1 +-1 +-1 +73 +-1 +80 +-1 +-1 +31 +-1 +43 +65 +57 +-1 +29 +30 +39 +79 +-1 +38 +-1 +-1 +-1 +-1 +-1 +80 +69 +-1 +-1 +-1 +67 +68 +75 +74 +37 +60 +80 +76 +-1 +-1 +-1 +59 +-1 +-1 +-1 +90 +-1 +19 +63 +23 +47 +96 +86 +91 +-1 +-1 +29 +32 +-1 +67 +-1 +72 +-1 +-1 +-1 +-1 +84 +-1 +-1 +-1 +56 +80 +67 +75 +93 +-1 +-1 +15 +71 +-1 +41 +-1 +-1 +-1 +-1 +-1 +16 +-1 +-1 +50 +68 +31 +46 +38 +84 +82 +-1 +-1 +77 +79 +99 +-1 +-1 +-1 +68 +-1 +-1 +37 +36 +-1 +93 +-1 +-1 +-1 +53 +-1 +-1 +14 +32 +51 +-1 +-1 +-1 +-1 +-1 +59 +-1 +28 +-1 +-1 +-1 +21 +99 +38 +82 +29 +-1 +-1 +-1 +-1 +26 +88 +28 +92 +60 +99 +-1 +-1 +-1 +53 +-1 +-1 +-1 +85 +-1 +-1 +-1 +40 +35 +28 +-1 +-1 +-1 +-1 +75 +-1 +14 +-1 +-1 +-1 +-1 +-1 +14 +-1 +-1 +-1 +-1 +17 +-1 +-1 +-1 +18 +16 +99 +99 +-1 +-1 +95 +-1 +54 +-1 +38 +-1 +28 +-1 +38 +79 +-1 +23 +41 +-1 +73 +-1 +-1 +-1 +-1 +52 +32 +-1 +27 +-1 +-1 +-1 +-1 +94 +-1 +-1 +37 +-1 +-1 +18 +100 +-1 +29 +-1 +-1 +90 +76 +28 +-1 +88 +-1 +-1 +-1 +-1 +63 +80 +-1 +71 +19 +63 +-1 +53 +-1 +99 +-1 +-1 +-1 +24 +27 +-1 +73 +-1 +-1 +-1 +48 +-1 +-1 +78 +34 +-1 +-1 +18 +-1 +66 +-1 +60 +86 +73 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k8_different_grid_sizes.txt new file mode 100644 index 0000000..961fe50 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +19 +46 +48 +65 +27 +34 +-1 +-1 +-1 +-1 +88 +-1 +69 +-1 +-1 +17 +-1 +-1 +-1 +-1 +62 +26 +-1 +-1 +-1 +-1 +-1 +89 +-1 +-1 +59 +22 +-1 +-1 +-1 +-1 +-1 +-1 +69 +-1 +55 +-1 +-1 +31 +62 +48 +88 +76 +64 +38 +78 +84 +81 +26 +33 +-1 +48 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +42 +-1 +-1 +35 +66 +94 +35 +94 +72 +73 +-1 +44 +33 +-1 +-1 +23 +-1 +27 +-1 +-1 +-1 +-1 +-1 +42 +26 +-1 +58 +89 +21 +95 +-1 +-1 +-1 +85 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k9.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k9.txt new file mode 100644 index 0000000..0b10358 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_5x5_k9.txt @@ -0,0 +1,1000 @@ +57 +72 +-1 +-1 +-1 +-1 +-1 +-1 +69 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +80 +-1 +99 +95 +-1 +58 +-1 +-1 +-1 +51 +-1 +-1 +-1 +-1 +-1 +-1 +98 +-1 +-1 +-1 +-1 +-1 +86 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +76 +89 +96 +-1 +91 +-1 +49 +-1 +-1 +68 +78 +63 +-1 +65 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +75 +-1 +-1 +-1 +-1 +40 +-1 +-1 +-1 +-1 +-1 +-1 +79 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +70 +-1 +-1 +-1 +-1 +-1 +64 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +63 +-1 +-1 +-1 +-1 +38 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +62 +-1 +-1 +-1 +-1 +-1 +-1 +67 +82 +-1 +-1 +-1 +-1 +43 +-1 +-1 +95 +-1 +-1 +55 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +62 +-1 +-1 +-1 +-1 +-1 +85 +48 +-1 +-1 +81 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +36 +65 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +67 +-1 +-1 +-1 +86 +-1 +40 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +94 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +50 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +72 +-1 +92 +-1 +-1 +-1 +75 +-1 +-1 +-1 +-1 +-1 +36 +-1 +-1 +-1 +-1 +39 +70 +-1 +-1 +-1 +91 +-1 +-1 +-1 +-1 +49 +-1 +-1 +-1 +-1 +87 +99 +-1 +-1 +43 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +77 +-1 +27 +-1 +-1 +-1 +-1 +38 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +54 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +83 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +57 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +57 +-1 +88 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +57 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +81 +93 +41 +-1 +-1 +-1 +-1 +-1 +46 +-1 +-1 +-1 +-1 +-1 +-1 +95 +-1 +-1 +-1 +-1 +-1 +-1 +73 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +95 +-1 +-1 +-1 +-1 +-1 +90 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +48 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +55 +-1 +52 +-1 +100 +-1 +-1 +-1 +-1 +-1 +-1 +35 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +73 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +70 +-1 +53 +-1 +79 +-1 +-1 +71 +-1 +-1 +-1 +-1 +90 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +63 +43 +-1 +53 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +48 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +73 +-1 +-1 +25 +-1 +-1 +29 +-1 +-1 +-1 +-1 +-1 +79 +-1 +-1 +19 +-1 +-1 +95 +-1 +-1 +60 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +90 +-1 +-1 +99 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +66 +-1 +-1 +-1 +-1 +77 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +58 +-1 +-1 +40 +-1 +-1 +-1 +-1 +49 +-1 +-1 +-1 +37 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +79 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +60 +-1 +41 +-1 +-1 +-1 +82 +-1 +-1 +-1 +95 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +34 +58 +-1 +88 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +91 +55 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +54 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +55 +-1 +-1 +42 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +49 +-1 +-1 +87 +-1 +-1 +79 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +88 +-1 +-1 +89 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +46 +-1 +100 +-1 +-1 +-1 +-1 +-1 +50 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +92 +65 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +36 +-1 +-1 +-1 +-1 +-1 +62 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +53 +-1 +-1 +-1 +-1 +85 +-1 +-1 +72 +-1 +-1 +-1 +-1 +-1 +-1 +84 +89 +33 +-1 +-1 +47 +-1 +-1 +-1 +-1 +-1 +52 +-1 +-1 +-1 +-1 +-1 +57 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +75 +44 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +49 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +25 +-1 +-1 +-1 +-1 +-1 +62 +-1 +-1 +-1 +56 +-1 +88 +-1 +-1 +78 +63 +36 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +82 +-1 +-1 +-1 +-1 +37 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +93 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_6x6_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_6x6_k8_different_grid_sizes.txt new file mode 100644 index 0000000..c21764c --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_6x6_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +63 +95 +89 +-1 +75 +-1 +-1 +-1 +-1 +86 +95 +43 +-1 +-1 +-1 +18 +35 +22 +-1 +-1 +54 +66 +41 +-1 +-1 +-1 +-1 +91 +-1 +-1 +-1 +-1 +97 +-1 +-1 +28 +-1 +54 +-1 +-1 +-1 +-1 +38 +-1 +-1 +-1 +-1 +-1 +22 +89 +-1 +-1 +-1 +-1 +-1 +83 +-1 +-1 +-1 +-1 +30 +30 +-1 +-1 +-1 +68 +-1 +-1 +18 +-1 +28 +-1 +-1 +44 +-1 +-1 +-1 +55 +69 +-1 +-1 +-1 +74 +-1 +23 +-1 +-1 +-1 +-1 +-1 +51 +-1 +-1 +-1 +88 +92 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_7x7_k10.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_7x7_k10.txt new file mode 100644 index 0000000..ed3977a --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_7x7_k10.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +58 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +83 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +74 +-1 +86 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +79 +-1 +-1 +93 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +98 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +84 +-1 +70 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +78 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +93 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +74 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +56 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +77 +-1 +-1 +95 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +47 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +72 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +84 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +96 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +45 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +85 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +85 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +69 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +98 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +98 +70 +-1 +-1 +-1 +-1 +-1 +93 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_7x7_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_7x7_k8_different_grid_sizes.txt new file mode 100644 index 0000000..11d884d --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_7x7_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +43 +48 +67 +25 +23 +66 +-1 +37 +-1 +-1 +-1 +41 +-1 +-1 +-1 +-1 +97 +-1 +-1 +-1 +51 +65 +-1 +31 +-1 +-1 +-1 +51 +21 +-1 +-1 +-1 +-1 +85 +30 +79 +-1 +-1 +-1 +62 +-1 +-1 +-1 +-1 +-1 +16 +-1 +25 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +56 +24 +-1 +-1 +33 +-1 +39 +-1 +94 +-1 +19 +89 +-1 +-1 +14 +78 +-1 +-1 +-1 +38 +-1 +15 +-1 +-1 +61 +-1 +36 +-1 +89 +-1 +-1 +14 +51 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_8x8_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_8x8_k8_different_grid_sizes.txt new file mode 100644 index 0000000..7ac1041 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_8x8_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +43 +54 +14 +57 +88 +-1 +-1 +-1 +-1 +-1 +27 +16 +-1 +66 +87 +37 +76 +-1 +-1 +-1 +37 +72 +53 +34 +88 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +26 +-1 +-1 +99 +-1 +-1 +49 +58 +-1 +-1 +-1 +49 +71 +39 +28 +-1 +-1 +-1 +-1 +-1 +39 +-1 +40 +-1 +-1 +-1 +-1 +27 +-1 +-1 +48 +-1 +49 +30 +35 +-1 +-1 +-1 +-1 +86 +97 +59 +-1 +55 +97 +72 +-1 +-1 +57 +-1 +-1 +16 +-1 +-1 +-1 +-1 +47 +-1 +37 +-1 +-1 +81 +-1 +44 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_9x9_k8_different_grid_sizes.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_9x9_k8_different_grid_sizes.txt new file mode 100644 index 0000000..69b2249 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_9x9_k8_different_grid_sizes.txt @@ -0,0 +1,100 @@ +26 +31 +45 +35 +-1 +-1 +-1 +-1 +-1 +-1 +42 +29 +-1 +29 +53 +37 +36 +35 +77 +-1 +-1 +52 +83 +-1 +-1 +-1 +-1 +30 +55 +-1 +64 +-1 +-1 +86 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +93 +39 +-1 +45 +-1 +-1 +-1 +-1 +25 +-1 +-1 +41 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +74 +50 +-1 +-1 +-1 +21 +82 +34 +-1 +32 +-1 +-1 +-1 +31 +-1 +65 +46 +-1 +50 +-1 +37 +-1 +53 +-1 +-1 +73 +-1 +94 +-1 +-1 +-1 +47 +36 +-1 +60 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_nikolaus.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_nikolaus.txt new file mode 100644 index 0000000..763fca9 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_nikolaus.txt @@ -0,0 +1,1000 @@ +2 +3 +3 +2 +2 +27 +2 +2 +2 +2 +17 +2 +3 +15 +2 +2 +2 +2 +3 +20 +3 +2 +2 +20 +10 +9 +10 +3 +12 +2 +18 +2 +2 +3 +2 +5 +2 +2 +6 +15 +8 +3 +2 +2 +2 +2 +2 +3 +2 +16 +2 +3 +2 +7 +2 +2 +2 +2 +13 +2 +2 +2 +3 +2 +2 +2 +3 +2 +3 +2 +18 +3 +2 +10 +2 +2 +2 +12 +2 +4 +6 +2 +3 +2 +2 +2 +20 +3 +3 +3 +2 +3 +2 +3 +2 +2 +6 +8 +2 +11 +9 +2 +3 +18 +3 +8 +2 +2 +16 +9 +2 +11 +11 +2 +-1 +2 +2 +9 +2 +2 +16 +2 +2 +9 +2 +2 +4 +2 +2 +2 +3 +2 +2 +15 +2 +10 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +11 +3 +2 +9 +2 +2 +2 +2 +2 +9 +4 +2 +2 +20 +2 +9 +11 +13 +7 +2 +2 +2 +10 +2 +5 +2 +2 +2 +8 +7 +2 +3 +8 +2 +6 +2 +2 +18 +2 +21 +2 +3 +2 +2 +2 +9 +3 +2 +2 +2 +2 +2 +2 +12 +3 +2 +15 +3 +3 +2 +2 +8 +3 +11 +17 +2 +2 +9 +2 +2 +2 +2 +2 +10 +8 +4 +4 +3 +2 +11 +21 +2 +18 +3 +17 +2 +3 +2 +23 +27 +18 +14 +16 +20 +2 +-1 +3 +2 +3 +2 +2 +10 +10 +3 +5 +2 +2 +2 +2 +2 +3 +2 +3 +2 +2 +2 +2 +9 +14 +2 +3 +10 +2 +3 +2 +2 +3 +2 +10 +15 +2 +15 +2 +2 +2 +2 +2 +3 +11 +16 +2 +12 +2 +10 +2 +5 +2 +2 +2 +3 +2 +2 +2 +-1 +2 +3 +2 +3 +7 +2 +3 +16 +2 +16 +3 +2 +3 +3 +4 +5 +2 +2 +2 +2 +2 +3 +5 +2 +9 +17 +8 +2 +2 +3 +2 +2 +3 +10 +3 +2 +2 +3 +19 +9 +2 +3 +2 +20 +2 +2 +2 +15 +2 +14 +2 +2 +22 +7 +9 +2 +2 +2 +9 +2 +2 +2 +2 +-1 +2 +2 +9 +3 +13 +2 +2 +12 +2 +2 +2 +3 +2 +2 +16 +3 +3 +3 +2 +4 +2 +2 +2 +2 +2 +5 +2 +2 +2 +2 +2 +2 +2 +2 +2 +7 +11 +2 +2 +3 +2 +11 +3 +8 +3 +2 +2 +11 +2 +2 +3 +3 +2 +2 +2 +2 +2 +18 +3 +2 +3 +2 +3 +2 +2 +2 +3 +2 +7 +3 +2 +2 +2 +3 +2 +9 +2 +3 +2 +2 +2 +2 +3 +13 +3 +2 +10 +2 +19 +3 +2 +3 +10 +3 +2 +2 +3 +3 +7 +2 +4 +2 +3 +2 +2 +2 +14 +15 +2 +2 +2 +3 +16 +2 +2 +2 +3 +2 +5 +14 +3 +4 +3 +2 +2 +3 +3 +10 +2 +8 +2 +19 +2 +2 +4 +2 +2 +11 +2 +2 +2 +3 +3 +7 +28 +2 +2 +9 +2 +2 +3 +3 +2 +2 +3 +9 +2 +16 +16 +3 +6 +3 +10 +2 +2 +2 +2 +2 +2 +2 +6 +2 +3 +3 +11 +2 +2 +3 +2 +2 +2 +2 +2 +3 +2 +3 +5 +2 +2 +2 +2 +3 +2 +2 +2 +2 +2 +7 +2 +2 +7 +13 +2 +2 +14 +2 +2 +2 +2 +2 +14 +2 +9 +10 +2 +2 +13 +2 +10 +2 +3 +2 +3 +6 +3 +2 +13 +2 +2 +2 +2 +15 +2 +2 +2 +9 +5 +2 +6 +4 +21 +2 +16 +2 +2 +2 +2 +2 +2 +2 +8 +5 +2 +2 +3 +5 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +27 +2 +2 +2 +3 +2 +13 +2 +11 +12 +12 +2 +18 +12 +3 +2 +13 +16 +2 +9 +22 +2 +2 +7 +2 +15 +2 +2 +2 +2 +12 +5 +2 +2 +2 +2 +2 +2 +2 +2 +7 +2 +6 +2 +5 +16 +2 +2 +9 +2 +2 +11 +2 +11 +31 +2 +14 +21 +2 +2 +2 +9 +2 +2 +2 +2 +2 +3 +3 +2 +2 +2 +2 +2 +6 +2 +3 +2 +2 +3 +2 +2 +10 +2 +2 +13 +38 +2 +2 +11 +12 +13 +2 +9 +2 +7 +13 +2 +2 +2 +3 +7 +2 +3 +2 +32 +2 +2 +2 +8 +9 +3 +2 +2 +3 +2 +17 +2 +4 +2 +3 +2 +2 +5 +2 +3 +3 +2 +3 +10 +4 +2 +2 +2 +20 +2 +13 +2 +2 +3 +2 +2 +16 +2 +4 +2 +7 +2 +2 +3 +3 +15 +2 +2 +2 +2 +3 +2 +2 +28 +2 +22 +2 +2 +2 +2 +12 +2 +11 +3 +2 +30 +10 +10 +41 +4 +15 +2 +3 +26 +3 +2 +2 +2 +2 +16 +3 +2 +2 +6 +2 +2 +3 +3 +2 +2 +2 +2 +3 +2 +2 +4 +2 +2 +12 +2 +2 +5 +2 +2 +2 +2 +3 +2 +5 +3 +3 +19 +2 +2 +6 +2 +2 +13 +3 +9 +3 +2 +3 +14 +3 +11 +3 +2 +18 +15 +3 +12 +27 +2 +2 +2 +3 +3 +2 +18 +9 +3 +13 +2 +2 +2 +9 +2 +2 +2 +2 +3 +3 +2 +7 +9 +4 +3 +8 +2 +7 +2 +10 +13 +2 +3 +2 +2 +16 +2 +26 +9 +26 +2 +11 +13 +2 +3 +9 +2 +3 +2 +2 +2 +2 +2 +3 +2 +3 +3 +5 +2 +2 +10 +2 +6 +2 +18 +2 +2 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +7 +4 +4 +8 +16 +3 +2 +2 +3 +2 +2 +3 +2 +2 +16 +2 +2 +2 +10 +2 +20 +2 +2 +2 +21 +3 +2 +2 +3 +2 +3 +3 +2 +3 +3 +2 +2 +3 +8 +2 +2 +2 +3 +2 +28 +2 +3 +15 diff --git a/python/plots/how_many_generations/data/k_graphs/how_many_generations_nikolaus_10000.txt b/python/plots/how_many_generations/data/k_graphs/how_many_generations_nikolaus_10000.txt new file mode 100644 index 0000000..ea6c439 --- /dev/null +++ b/python/plots/how_many_generations/data/k_graphs/how_many_generations_nikolaus_10000.txt @@ -0,0 +1,10000 @@ +11 +3 +3 +11 +10 +2 +23 +2 +7 +15 +2 +2 +6 +3 +15 +20 +2 +3 +2 +2 +3 +12 +2 +13 +7 +3 +2 +2 +3 +2 +25 +3 +2 +21 +2 +14 +2 +13 +12 +28 +12 +15 +2 +2 +3 +7 +-1 +9 +18 +2 +2 +3 +19 +14 +2 +3 +2 +2 +18 +4 +13 +11 +7 +16 +2 +3 +2 +2 +2 +6 +15 +9 +2 +2 +2 +6 +3 +28 +11 +15 +2 +2 +2 +3 +3 +2 +2 +2 +2 +2 +6 +2 +11 +3 +2 +17 +2 +13 +3 +2 +2 +8 +2 +2 +2 +2 +2 +2 +2 +19 +2 +2 +2 +8 +3 +3 +2 +2 +2 +2 +2 +9 +2 +3 +2 +2 +2 +2 +12 +3 +3 +3 +5 +2 +3 +21 +3 +14 +5 +3 +2 +2 +2 +3 +2 +3 +9 +2 +2 +29 +2 +9 +13 +2 +2 +2 +2 +3 +3 +7 +2 +24 +13 +2 +2 +2 +7 +2 +3 +5 +2 +7 +2 +2 +16 +2 +9 +2 +10 +15 +2 +2 +2 +10 +2 +2 +3 +12 +18 +3 +10 +2 +2 +2 +2 +17 +3 +3 +2 +2 +12 +12 +2 +17 +2 +2 +3 +3 +2 +14 +2 +2 +9 +8 +3 +2 +7 +2 +-1 +2 +2 +2 +2 +9 +2 +2 +2 +2 +2 +6 +3 +2 +15 +2 +2 +17 +12 +5 +3 +3 +20 +2 +3 +2 +2 +2 +3 +3 +2 +5 +3 +2 +20 +2 +2 +22 +2 +13 +8 +2 +3 +3 +2 +2 +2 +15 +2 +10 +2 +24 +3 +2 +3 +2 +2 +3 +12 +2 +2 +4 +4 +2 +4 +3 +2 +2 +3 +8 +8 +9 +2 +3 +2 +12 +3 +2 +2 +3 +22 +12 +6 +2 +23 +2 +3 +2 +2 +3 +2 +2 +3 +3 +2 +3 +2 +3 +2 +2 +7 +3 +2 +15 +8 +2 +2 +3 +3 +2 +4 +2 +3 +2 +2 +3 +2 +21 +2 +2 +2 +2 +2 +2 +13 +2 +9 +2 +14 +22 +3 +2 +3 +6 +27 +2 +3 +2 +3 +12 +2 +2 +2 +2 +2 +3 +2 +3 +2 +21 +3 +3 +2 +8 +8 +2 +7 +2 +2 +2 +9 +2 +16 +2 +2 +2 +2 +3 +2 +9 +3 +3 +22 +2 +2 +8 +10 +2 +2 +3 +8 +2 +2 +9 +2 +6 +3 +2 +-1 +3 +7 +3 +2 +28 +9 +2 +2 +2 +2 +3 +2 +12 +8 +13 +2 +2 +2 +2 +2 +18 +7 +2 +2 +2 +2 +2 +6 +2 +2 +2 +2 +3 +3 +2 +2 +2 +2 +3 +3 +2 +2 +2 +8 +2 +2 +2 +2 +3 +2 +16 +2 +2 +3 +2 +5 +2 +13 +2 +2 +3 +15 +2 +9 +8 +7 +-1 +2 +2 +3 +2 +2 +14 +3 +2 +2 +2 +2 +6 +2 +2 +9 +2 +5 +16 +2 +2 +14 +2 +19 +5 +5 +2 +2 +9 +2 +2 +25 +10 +2 +19 +2 +2 +-1 +2 +2 +3 +3 +2 +2 +3 +2 +3 +10 +3 +2 +3 +9 +3 +2 +2 +18 +2 +7 +17 +2 +2 +3 +2 +2 +2 +2 +15 +4 +2 +3 +3 +3 +9 +2 +2 +12 +2 +3 +22 +2 +2 +2 +9 +15 +3 +5 +3 +10 +10 +3 +2 +3 +2 +11 +14 +3 +20 +2 +4 +9 +2 +3 +2 +2 +2 +2 +2 +29 +3 +9 +4 +2 +3 +3 +2 +2 +2 +16 +3 +4 +2 +18 +3 +2 +2 +2 +2 +5 +2 +3 +2 +2 +4 +15 +11 +21 +2 +2 +3 +7 +9 +2 +10 +2 +6 +3 +2 +2 +2 +2 +12 +2 +2 +3 +13 +2 +2 +12 +2 +2 +2 +2 +2 +10 +9 +4 +4 +5 +3 +8 +4 +2 +3 +3 +9 +2 +2 +8 +3 +2 +3 +18 +2 +3 +5 +2 +2 +2 +2 +2 +2 +19 +4 +3 +16 +2 +2 +2 +16 +2 +19 +2 +10 +2 +2 +9 +2 +2 +2 +3 +2 +2 +2 +2 +2 +2 +2 +2 +3 +2 +10 +2 +6 +3 +3 +2 +2 +2 +2 +2 +2 +3 +2 +5 +2 +2 +2 +2 +2 +2 +2 +2 +15 +2 +2 +14 +2 +2 +8 +2 +2 +10 +2 +14 +3 +7 +10 +10 +2 +16 +2 +2 +2 +2 +2 +3 +2 +15 +12 +2 +16 +14 +13 +8 +6 +2 +2 +6 +2 +2 +2 +2 +2 +3 +9 +8 +3 +2 +3 +2 +4 +3 +20 +2 +2 +7 +3 +2 +2 +3 +2 +2 +3 +2 +2 +19 +2 +2 +2 +13 +2 +2 +2 +3 +11 +15 +2 +12 +11 +2 +28 +8 +12 +17 +25 +6 +2 +2 +21 +2 +2 +2 +4 +15 +2 +2 +14 +3 +13 +20 +2 +-1 +2 +9 +11 +2 +2 +2 +2 +11 +2 +2 +5 +2 +8 +3 +3 +3 +2 +8 +11 +7 +2 +2 +2 +2 +2 +2 +2 +2 +6 +2 +7 +15 +9 +18 +2 +37 +3 +14 +2 +2 +4 +2 +3 +2 +2 +2 +2 +24 +2 +2 +2 +3 +2 +8 +2 +2 +3 +3 +2 +2 +2 +4 +3 +2 +3 +24 +12 +2 +5 +2 +3 +2 +2 +2 +2 +3 +2 +2 +16 +32 +2 +2 +5 +3 +2 +2 +2 +2 +2 +10 +3 +2 +2 +5 +5 +5 +3 +12 +2 +2 +2 +3 +2 +18 +9 +2 +3 +2 +12 +2 +3 +2 +2 +2 +7 +3 +3 +2 +2 +2 +2 +14 +2 +3 +25 +17 +17 +6 +17 +12 +10 +2 +28 +11 +12 +8 +2 +3 +3 +9 +4 +14 +16 +2 +2 +3 +13 +2 +17 +6 +2 +2 +2 +10 +5 +3 +12 +2 +2 +10 +3 +2 +4 +7 +14 +2 +2 +2 +6 +2 +4 +10 +2 +5 +8 +10 +8 +5 +2 +4 +3 +3 +2 +2 +3 +28 +14 +5 +5 +3 +3 +2 +13 +2 +3 +2 +2 +2 +2 +4 +4 +3 +17 +6 +2 +2 +10 +3 +2 +2 +2 +12 +3 +2 +2 +10 +3 +8 +3 +2 +3 +15 +2 +11 +6 +2 +2 +24 +19 +11 +2 +3 +11 +3 +2 +7 +2 +2 +2 +19 +8 +2 +2 +2 +2 +10 +2 +3 +5 +10 +2 +2 +2 +2 +6 +5 +11 +12 +15 +9 +2 +2 +2 +3 +3 +2 +4 +9 +16 +3 +3 +14 +3 +16 +3 +4 +17 +19 +3 +2 +2 +2 +2 +5 +2 +2 +2 +2 +2 +11 +15 +19 +2 +3 +2 +2 +5 +3 +2 +2 +3 +3 +2 +3 +13 +6 +2 +2 +2 +3 +2 +10 +5 +2 +2 +2 +11 +2 +3 +2 +11 +3 +3 +2 +3 +2 +9 +2 +2 +2 +3 +20 +12 +10 +3 +5 +3 +2 +27 +2 +18 +2 +10 +2 +18 +3 +2 +9 +5 +2 +2 +4 +3 +7 +4 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +2 +2 +2 +-1 +3 +2 +5 +2 +2 +4 +3 +2 +2 +2 +2 +2 +2 +2 +2 +3 +2 +3 +6 +2 +2 +2 +2 +16 +3 +2 +9 +2 +3 +2 +14 +2 +2 +8 +12 +24 +2 +8 +13 +2 +2 +2 +2 +16 +2 +3 +2 +2 +2 +2 +2 +2 +21 +2 +3 +6 +11 +3 +2 +8 +2 +2 +-1 +2 +2 +2 +2 +24 +3 +2 +2 +6 +2 +20 +2 +2 +3 +2 +2 +2 +11 +3 +2 +2 +5 +2 +2 +3 +21 +2 +2 +20 +2 +11 +2 +3 +5 +2 +2 +3 +16 +19 +4 +4 +2 +2 +2 +5 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +2 +2 +2 +16 +2 +6 +11 +12 +7 +4 +2 +3 +2 +2 +2 +2 +2 +3 +15 +13 +3 +2 +2 +7 +2 +2 +16 +2 +2 +3 +2 +2 +2 +9 +6 +9 +19 +3 +3 +16 +2 +8 +3 +2 +2 +2 +2 +2 +-1 +2 +2 +3 +12 +4 +13 +3 +14 +3 +11 +9 +2 +11 +2 +3 +5 +2 +3 +14 +2 +2 +2 +2 +2 +3 +2 +9 +16 +3 +2 +3 +18 +2 +2 +13 +2 +21 +2 +8 +3 +15 +9 +2 +3 +3 +2 +2 +2 +2 +2 +2 +2 +11 +2 +5 +2 +3 +8 +3 +4 +2 +2 +19 +2 +16 +3 +2 +2 +14 +12 +2 +3 +12 +2 +2 +2 +2 +2 +3 +3 +2 +2 +-1 +2 +3 +5 +2 +3 +2 +2 +2 +23 +17 +13 +2 +3 +2 +2 +2 +3 +2 +3 +3 +2 +10 +2 +3 +2 +3 +2 +3 +2 +2 +3 +2 +2 +3 +28 +2 +2 +9 +3 +2 +2 +12 +9 +2 +9 +3 +2 +17 +2 +3 +2 +17 +2 +2 +2 +2 +3 +2 +17 +3 +13 +2 +6 +8 +15 +11 +3 +2 +2 +2 +3 +12 +18 +3 +23 +2 +15 +2 +2 +2 +3 +17 +2 +14 +-1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +11 +18 +2 +19 +2 +2 +2 +2 +2 +2 +2 +8 +2 +2 +2 +6 +2 +3 +3 +3 +16 +3 +2 +2 +2 +2 +10 +2 +22 +2 +11 +2 +4 +2 +2 +18 +2 +3 +2 +2 +3 +2 +2 +11 +2 +3 +4 +3 +2 +2 +2 +3 +2 +6 +2 +3 +3 +2 +12 +2 +2 +2 +5 +2 +3 +2 +2 +2 +4 +2 +11 +2 +2 +18 +2 +3 +16 +3 +16 +3 +3 +2 +2 +2 +2 +2 +2 +8 +13 +2 +2 +3 +3 +2 +2 +3 +5 +2 +4 +2 +2 +16 +2 +8 +11 +2 +15 +2 +2 +13 +4 +2 +3 +2 +2 +2 +4 +3 +2 +10 +14 +2 +2 +19 +14 +2 +2 +5 +2 +7 +2 +6 +2 +2 +18 +2 +3 +14 +2 +2 +8 +2 +2 +2 +8 +3 +2 +8 +18 +2 +2 +2 +19 +2 +2 +25 +14 +3 +2 +6 +12 +21 +2 +2 +3 +3 +2 +2 +2 +2 +19 +5 +6 +2 +2 +2 +15 +2 +2 +3 +2 +4 +2 +2 +3 +2 +9 +7 +2 +10 +2 +2 +3 +45 +3 +3 +3 +2 +2 +2 +2 +4 +6 +2 +2 +8 +26 +2 +6 +3 +2 +2 +14 +12 +2 +8 +3 +7 +3 +2 +3 +3 +3 +3 +11 +12 +3 +3 +2 +2 +2 +2 +3 +2 +2 +2 +3 +22 +-1 +3 +2 +2 +2 +2 +2 +4 +2 +24 +4 +3 +2 +6 +2 +2 +2 +11 +2 +-1 +2 +2 +6 +3 +2 +3 +2 +6 +2 +17 +2 +2 +6 +2 +10 +2 +2 +3 +2 +2 +2 +17 +9 +4 +2 +6 +7 +2 +2 +2 +2 +2 +3 +2 +3 +23 +2 +2 +22 +3 +2 +2 +-1 +2 +16 +3 +2 +2 +2 +3 +2 +3 +9 +16 +2 +2 +3 +2 +2 +2 +2 +11 +3 +2 +2 +2 +3 +2 +25 +10 +2 +18 +2 +2 +2 +3 +3 +18 +11 +2 +2 +2 +2 +4 +2 +8 +5 +2 +2 +2 +2 +2 +2 +7 +2 +2 +2 +2 +-1 +2 +2 +3 +2 +3 +9 +2 +2 +2 +2 +15 +2 +2 +2 +2 +2 +11 +3 +2 +2 +2 +2 +13 +2 +3 +2 +17 +3 +2 +2 +3 +4 +3 +2 +16 +8 +2 +8 +3 +2 +17 +11 +9 +2 +31 +4 +3 +2 +3 +2 +12 +2 +2 +2 +2 +2 +3 +2 +5 +2 +2 +3 +2 +2 +12 +2 +2 +8 +3 +2 +2 +10 +10 +19 +2 +4 +3 +3 +21 +2 +8 +2 +2 +2 +2 +4 +2 +5 +2 +5 +3 +9 +2 +11 +3 +2 +3 +2 +4 +21 +2 +9 +2 +21 +2 +19 +2 +2 +3 +2 +2 +18 +2 +3 +2 +2 +2 +2 +25 +2 +2 +2 +2 +2 +12 +3 +4 +3 +2 +2 +19 +4 +4 +8 +3 +3 +8 +2 +3 +2 +2 +2 +20 +11 +3 +20 +2 +17 +2 +2 +2 +2 +2 +3 +3 +3 +2 +4 +2 +2 +7 +3 +5 +6 +2 +7 +8 +2 +2 +2 +4 +2 +13 +2 +10 +2 +3 +14 +3 +14 +2 +2 +14 +2 +13 +16 +2 +2 +6 +3 +2 +16 +8 +21 +11 +2 +5 +2 +2 +2 +3 +5 +7 +6 +11 +2 +3 +8 +2 +2 +2 +2 +8 +3 +2 +2 +2 +15 +2 +2 +3 +2 +9 +2 +2 +3 +10 +3 +2 +2 +2 +2 +19 +11 +2 +30 +3 +2 +3 +3 +2 +19 +6 +-1 +2 +2 +12 +2 +3 +9 +2 +2 +3 +11 +2 +3 +2 +2 +13 +3 +2 +2 +2 +9 +2 +2 +10 +3 +3 +2 +5 +12 +2 +3 +2 +2 +2 +3 +9 +2 +2 +15 +3 +3 +14 +2 +2 +3 +2 +2 +2 +3 +3 +2 +2 +2 +2 +2 +2 +17 +2 +3 +2 +2 +2 +2 +2 +4 +2 +3 +3 +2 +2 +3 +2 +9 +2 +2 +2 +2 +10 +2 +2 +2 +3 +2 +19 +8 +2 +2 +2 +3 +2 +8 +41 +2 +2 +2 +13 +9 +19 +2 +2 +6 +3 +7 +17 +2 +2 +2 +9 +2 +2 +10 +2 +2 +3 +2 +2 +2 +4 +2 +18 +2 +10 +2 +2 +34 +2 +12 +20 +2 +2 +8 +2 +2 +2 +9 +13 +3 +10 +3 +2 +2 +3 +3 +5 +8 +2 +2 +2 +7 +2 +6 +3 +2 +2 +8 +2 +2 +3 +2 +2 +14 +3 +2 +6 +2 +28 +19 +2 +6 +10 +2 +3 +2 +3 +2 +37 +10 +2 +3 +2 +2 +12 +2 +7 +5 +14 +2 +10 +11 +2 +3 +9 +2 +6 +2 +2 +3 +3 +2 +2 +2 +2 +3 +2 +2 +2 +18 +2 +2 +3 +2 +4 +2 +27 +2 +2 +10 +2 +11 +2 +15 +2 +3 +3 +8 +6 +3 +2 +2 +17 +2 +14 +4 +2 +3 +17 +2 +4 +2 +2 +2 +2 +10 +3 +2 +10 +7 +2 +2 +2 +2 +2 +2 +16 +3 +2 +4 +32 +17 +23 +2 +14 +3 +2 +3 +2 +13 +2 +3 +3 +2 +2 +2 +5 +2 +2 +2 +10 +2 +6 +2 +3 +3 +2 +24 +2 +3 +2 +11 +3 +22 +2 +2 +3 +3 +2 +2 +2 +5 +2 +2 +2 +2 +2 +6 +2 +2 +24 +3 +2 +3 +6 +2 +4 +2 +2 +11 +2 +9 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +13 +3 +3 +30 +2 +4 +15 +2 +2 +2 +3 +2 +2 +3 +2 +19 +2 +2 +2 +3 +2 +2 +2 +2 +6 +2 +6 +19 +2 +2 +3 +7 +3 +12 +2 +4 +2 +2 +2 +2 +2 +2 +2 +2 +2 +7 +2 +2 +2 +12 +4 +6 +8 +2 +2 +2 +16 +17 +2 +3 +2 +12 +2 +2 +2 +3 +10 +2 +2 +2 +6 +2 +3 +3 +3 +5 +13 +11 +2 +2 +8 +14 +6 +3 +17 +2 +3 +2 +12 +2 +2 +2 +2 +6 +3 +8 +2 +2 +3 +3 +3 +7 +2 +4 +2 +4 +12 +22 +2 +3 +2 +10 +2 +2 +3 +2 +2 +9 +2 +2 +2 +3 +2 +3 +2 +2 +2 +2 +2 +2 +2 +3 +3 +2 +3 +18 +2 +3 +11 +2 +8 +6 +2 +2 +20 +3 +19 +2 +9 +3 +2 +17 +13 +2 +5 +2 +2 +3 +3 +10 +2 +2 +8 +25 +17 +2 +3 +2 +2 +4 +3 +2 +-1 +3 +3 +2 +2 +20 +3 +4 +2 +3 +2 +2 +11 +2 +10 +2 +2 +2 +2 +2 +2 +11 +2 +2 +3 +10 +2 +3 +8 +3 +3 +2 +-1 +13 +3 +2 +3 +2 +28 +3 +17 +3 +3 +26 +2 +6 +2 +2 +2 +2 +2 +3 +2 +5 +2 +11 +2 +2 +10 +4 +2 +2 +3 +3 +2 +2 +2 +2 +2 +9 +3 +2 +2 +2 +3 +2 +2 +4 +2 +2 +2 +2 +11 +3 +2 +17 +2 +2 +14 +19 +2 +4 +3 +2 +7 +2 +2 +12 +2 +-1 +2 +3 +3 +3 +3 +2 +2 +3 +7 +2 +2 +2 +2 +15 +3 +2 +2 +5 +4 +2 +2 +10 +2 +2 +9 +2 +2 +2 +10 +15 +8 +2 +2 +2 +13 +2 +2 +3 +3 +13 +14 +8 +2 +11 +2 +7 +2 +13 +30 +24 +2 +2 +3 +2 +3 +2 +2 +3 +14 +13 +15 +2 +2 +45 +3 +6 +16 +20 +2 +33 +2 +18 +2 +2 +2 +3 +11 +2 +10 +3 +17 +3 +2 +2 +2 +28 +14 +2 +2 +8 +4 +2 +3 +2 +2 +6 +14 +7 +3 +2 +14 +2 +15 +6 +2 +3 +16 +10 +11 +2 +2 +2 +3 +3 +2 +2 +2 +2 +3 +3 +3 +2 +8 +2 +3 +13 +3 +2 +10 +2 +17 +2 +14 +2 +2 +2 +13 +2 +2 +2 +19 +17 +2 +2 +24 +2 +3 +8 +2 +2 +2 +2 +2 +2 +5 +2 +2 +2 +5 +3 +2 +2 +3 +2 +2 +3 +2 +2 +3 +2 +2 +15 +11 +10 +2 +2 +2 +13 +2 +2 +3 +8 +2 +2 +2 +12 +2 +8 +2 +3 +2 +8 +11 +3 +5 +15 +15 +9 +2 +3 +2 +2 +2 +2 +12 +2 +15 +2 +12 +2 +2 +2 +2 +3 +2 +12 +2 +2 +2 +2 +19 +2 +3 +2 +2 +2 +19 +2 +3 +3 +7 +3 +2 +22 +2 +2 +2 +2 +2 +8 +2 +2 +2 +3 +32 +2 +3 +12 +2 +4 +4 +2 +15 +10 +2 +2 +2 +3 +2 +18 +18 +3 +17 +3 +2 +9 +6 +2 +2 +2 +10 +17 +3 +2 +10 +2 +6 +3 +2 +6 +2 +2 +2 +2 +9 +6 +18 +2 +2 +2 +2 +3 +2 +2 +10 +3 +7 +3 +19 +2 +5 +6 +11 +2 +2 +2 +8 +2 +2 +2 +2 +2 +2 +17 +2 +2 +3 +2 +2 +3 +2 +12 +2 +6 +2 +3 +3 +2 +2 +8 +25 +2 +2 +3 +6 +3 +18 +20 +2 +2 +3 +2 +3 +3 +8 +2 +6 +2 +2 +2 +2 +8 +2 +2 +2 +2 +2 +2 +2 +10 +3 +2 +2 +4 +13 +7 +2 +2 +2 +3 +2 +11 +2 +2 +2 +5 +3 +2 +10 +2 +2 +15 +3 +3 +10 +18 +16 +7 +2 +3 +2 +2 +17 +10 +2 +2 +2 +2 +3 +5 +2 +2 +10 +2 +8 +3 +2 +3 +16 +3 +2 +3 +2 +2 +2 +3 +2 +2 +3 +2 +14 +3 +3 +14 +2 +2 +2 +12 +11 +2 +2 +2 +3 +2 +2 +2 +12 +2 +4 +2 +15 +2 +15 +8 +2 +2 +16 +3 +3 +3 +2 +2 +3 +2 +2 +3 +2 +11 +2 +4 +3 +2 +2 +2 +18 +-1 +2 +2 +3 +2 +4 +3 +2 +11 +11 +2 +3 +6 +2 +8 +12 +2 +3 +6 +2 +3 +3 +4 +2 +2 +3 +2 +3 +3 +2 +5 +2 +2 +2 +2 +2 +3 +2 +2 +2 +11 +2 +11 +2 +3 +3 +10 +2 +2 +15 +11 +2 +2 +2 +19 +8 +2 +2 +2 +2 +2 +2 +10 +2 +3 +9 +3 +6 +2 +10 +2 +2 +2 +2 +3 +3 +18 +2 +10 +2 +11 +3 +2 +3 +2 +9 +4 +3 +2 +2 +2 +3 +2 +15 +3 +2 +2 +2 +2 +12 +3 +2 +14 +10 +21 +5 +2 +5 +2 +2 +2 +2 +7 +2 +2 +2 +2 +2 +2 +4 +2 +2 +2 +2 +2 +3 +3 +6 +2 +2 +2 +2 +2 +3 +3 +2 +7 +2 +2 +2 +15 +2 +13 +9 +2 +8 +17 +17 +2 +2 +2 +2 +8 +3 +7 +5 +3 +2 +2 +8 +8 +2 +2 +2 +2 +12 +3 +2 +2 +2 +3 +2 +3 +2 +2 +2 +2 +16 +2 +2 +2 +3 +2 +2 +3 +2 +2 +2 +2 +7 +3 +2 +2 +2 +2 +10 +2 +19 +2 +2 +3 +4 +2 +2 +2 +9 +2 +2 +2 +3 +3 +2 +2 +2 +4 +28 +2 +3 +2 +18 +3 +17 +9 +2 +3 +10 +2 +3 +2 +2 +2 +3 +3 +15 +8 +3 +2 +2 +21 +15 +2 +27 +2 +15 +30 +20 +2 +3 +2 +2 +2 +19 +3 +2 +3 +2 +9 +2 +2 +12 +9 +11 +2 +3 +2 +2 +4 +7 +3 +3 +22 +3 +10 +2 +2 +2 +3 +10 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +18 +2 +2 +2 +2 +2 +2 +2 +3 +9 +3 +2 +2 +18 +9 +2 +2 +2 +13 +2 +3 +2 +2 +20 +3 +2 +13 +2 +3 +7 +2 +2 +2 +11 +10 +3 +3 +2 +3 +3 +2 +2 +2 +14 +3 +2 +3 +15 +9 +2 +32 +2 +2 +14 +2 +2 +2 +3 +2 +2 +9 +26 +2 +19 +2 +2 +2 +3 +2 +2 +2 +2 +2 +11 +6 +2 +4 +18 +2 +32 +9 +8 +2 +2 +8 +3 +8 +2 +9 +2 +3 +7 +2 +2 +2 +2 +3 +3 +2 +2 +2 +2 +9 +2 +2 +5 +2 +8 +2 +17 +13 +3 +31 +28 +2 +2 +2 +3 +3 +2 +2 +6 +25 +2 +3 +16 +3 +9 +14 +2 +9 +26 +3 +2 +3 +2 +3 +10 +2 +2 +44 +2 +2 +14 +2 +2 +4 +22 +2 +6 +9 +2 +3 +3 +2 +4 +2 +10 +2 +3 +2 +3 +3 +2 +2 +23 +2 +3 +22 +3 +2 +2 +3 +2 +2 +2 +11 +19 +2 +2 +3 +7 +4 +2 +2 +2 +3 +18 +12 +40 +3 +10 +3 +2 +2 +2 +2 +3 +2 +2 +4 +14 +2 +11 +12 +12 +2 +11 +2 +3 +2 +8 +2 +15 +2 +2 +2 +2 +5 +11 +2 +4 +4 +2 +2 +14 +5 +9 +13 +2 +2 +3 +5 +2 +30 +3 +4 +2 +2 +2 +31 +2 +2 +3 +2 +16 +2 +2 +2 +2 +2 +8 +2 +2 +2 +2 +2 +2 +11 +3 +2 +4 +15 +28 +17 +3 +-1 +33 +2 +2 +11 +2 +4 +14 +13 +8 +2 +2 +2 +3 +2 +3 +5 +3 +2 +2 +2 +2 +2 +2 +2 +2 +7 +2 +20 +16 +2 +2 +5 +2 +2 +2 +2 +6 +2 +2 +8 +2 +16 +6 +10 +3 +2 +14 +8 +2 +2 +13 +3 +2 +2 +2 +3 +2 +9 +8 +2 +3 +13 +11 +5 +17 +2 +7 +20 +2 +3 +6 +22 +2 +3 +2 +2 +2 +2 +2 +11 +4 +2 +4 +8 +2 +3 +2 +2 +2 +2 +16 +2 +2 +7 +2 +2 +5 +37 +2 +2 +2 +7 +2 +13 +3 +7 +2 +6 +40 +15 +3 +2 +14 +4 +2 +4 +2 +15 +2 +2 +8 +3 +2 +4 +11 +2 +2 +3 +2 +11 +10 +2 +7 +2 +2 +3 +2 +2 +7 +11 +2 +2 +7 +3 +2 +2 +15 +-1 +3 +9 +2 +2 +28 +2 +2 +3 +-1 +3 +21 +15 +2 +6 +12 +2 +3 +2 +2 +3 +3 +2 +4 +2 +2 +2 +6 +2 +2 +2 +2 +2 +2 +9 +7 +2 +10 +18 +5 +15 +5 +11 +2 +3 +2 +2 +10 +2 +2 +12 +3 +2 +2 +21 +2 +3 +2 +4 +3 +3 +6 +8 +15 +11 +2 +2 +2 +23 +12 +2 +18 +2 +2 +4 +2 +2 +17 +2 +2 +2 +2 +13 +5 +2 +3 +2 +11 +24 +8 +2 +-1 +3 +9 +2 +2 +21 +2 +2 +2 +2 +2 +2 +4 +2 +10 +16 +7 +2 +14 +46 +3 +5 +2 +2 +3 +3 +2 +4 +2 +17 +2 +6 +8 +2 +23 +2 +2 +16 +2 +2 +9 +2 +6 +3 +9 +2 +2 +2 +2 +12 +3 +12 +12 +2 +3 +2 +2 +6 +5 +3 +3 +2 +3 +2 +3 +2 +2 +7 +8 +9 +6 +3 +2 +3 +8 +2 +17 +3 +19 +2 +2 +3 +2 +3 +4 +10 +2 +3 +3 +4 +3 +7 +4 +2 +2 +2 +2 +3 +5 +14 +2 +2 +2 +2 +4 +3 +2 +3 +2 +2 +3 +13 +2 +13 +2 +2 +2 +2 +11 +2 +7 +2 +3 +2 +14 +3 +10 +18 +8 +2 +20 +2 +2 +2 +2 +2 +3 +3 +3 +2 +2 +2 +7 +2 +8 +2 +8 +2 +3 +3 +3 +18 +4 +2 +3 +5 +2 +3 +2 +2 +9 +3 +2 +11 +3 +3 +16 +3 +2 +16 +2 +3 +2 +8 +2 +2 +3 +2 +2 +2 +2 +2 +19 +2 +3 +3 +2 +2 +11 +33 +2 +2 +2 +2 +2 +19 +3 +2 +2 +2 +2 +2 +4 +9 +2 +10 +2 +2 +7 +3 +2 +2 +10 +2 +2 +20 +2 +18 +2 +2 +16 +4 +2 +9 +3 +2 +3 +2 +5 +2 +16 +19 +2 +3 +34 +8 +2 +2 +3 +2 +2 +2 +21 +2 +3 +2 +3 +3 +13 +11 +3 +2 +2 +3 +2 +18 +2 +59 +2 +3 +2 +2 +2 +2 +3 +3 +2 +3 +9 +16 +2 +2 +2 +2 +2 +2 +20 +2 +2 +5 +6 +2 +2 +2 +8 +5 +16 +2 +2 +2 +3 +2 +2 +3 +2 +2 +2 +7 +3 +2 +2 +2 +2 +3 +2 +2 +2 +2 +2 +2 +2 +9 +4 +2 +13 +2 +2 +2 +3 +18 +2 +2 +2 +-1 +4 +2 +2 +3 +2 +11 +2 +12 +2 +2 +2 +24 +2 +4 +8 +8 +18 +2 +2 +2 +2 +7 +2 +6 +2 +12 +2 +3 +3 +16 +3 +10 +2 +2 +3 +2 +3 +16 +6 +7 +10 +13 +3 +2 +3 +2 +2 +11 +2 +2 +2 +2 +2 +2 +4 +4 +2 +10 +2 +3 +17 +18 +2 +12 +2 +21 +3 +10 +13 +2 +2 +2 +6 +2 +2 +2 +2 +3 +2 +2 +2 +2 +2 +3 +14 +8 +5 +3 +2 +3 +2 +3 +2 +3 +2 +3 +2 +2 +2 +2 +24 +2 +9 +2 +2 +4 +2 +14 +3 +5 +14 +2 +3 +30 +10 +15 +3 +2 +2 +9 +23 +2 +2 +2 +2 +2 +2 +3 +3 +15 +9 +8 +2 +2 +28 +2 +2 +27 +7 +10 +17 +2 +6 +2 +7 +2 +3 +2 +3 +2 +2 +8 +11 +7 +3 +11 +14 +2 +14 +2 +2 +3 +2 +3 +5 +17 +17 +2 +19 +3 +3 +3 +17 +2 +2 +8 +3 +3 +3 +9 +2 +2 +15 +2 +2 +2 +16 +3 +2 +2 +3 +2 +2 +2 +2 +3 +32 +2 +8 +2 +3 +4 +2 +10 +6 +8 +2 +4 +2 +2 +15 +2 +7 +2 +2 +2 +3 +4 +2 +2 +3 +14 +4 +2 +2 +2 +7 +3 +2 +2 +19 +2 +2 +3 +2 +2 +3 +10 +22 +2 +2 +2 +3 +2 +30 +9 +2 +2 +13 +2 +2 +2 +12 +2 +2 +3 +2 +21 +3 +11 +2 +4 +2 +2 +2 +2 +3 +2 +12 +3 +2 +2 +2 +3 +3 +2 +2 +2 +4 +14 +2 +2 +9 +6 +2 +3 +2 +2 +2 +2 +2 +2 +2 +9 +2 +3 +3 +3 +5 +2 +3 +2 +16 +4 +3 +2 +2 +3 +18 +2 +3 +2 +2 +2 +2 +2 +6 +2 +3 +3 +2 +2 +10 +-1 +2 +2 +3 +3 +3 +2 +2 +5 +2 +2 +2 +2 +2 +10 +17 +2 +8 +3 +12 +8 +2 +9 +21 +12 +13 +3 +2 +11 +3 +5 +2 +2 +2 +2 +7 +11 +2 +13 +2 +11 +8 +2 +2 +2 +2 +8 +2 +2 +2 +2 +3 +3 +26 +2 +2 +2 +7 +6 +2 +3 +2 +2 +2 +3 +3 +2 +3 +4 +3 +2 +17 +2 +3 +2 +14 +2 +10 +4 +10 +-1 +2 +2 +16 +3 +4 +2 +48 +2 +3 +3 +4 +2 +16 +23 +2 +2 +2 +14 +10 +2 +3 +2 +2 +6 +2 +5 +2 +2 +2 +2 +8 +12 +23 +2 +2 +10 +28 +2 +6 +3 +2 +2 +2 +2 +14 +3 +15 +2 +5 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +11 +7 +2 +3 +25 +-1 +2 +2 +2 +5 +7 +12 +2 +2 +3 +2 +2 +2 +-1 +2 +2 +3 +7 +3 +18 +7 +23 +12 +6 +14 +5 +3 +2 +2 +3 +3 +6 +2 +3 +2 +2 +10 +2 +16 +2 +2 +2 +2 +2 +2 +2 +7 +3 +2 +7 +5 +3 +2 +2 +3 +15 +10 +2 +8 +3 +2 +2 +3 +2 +2 +3 +3 +2 +2 +21 +17 +2 +2 +7 +2 +2 +2 +2 +2 +12 +2 +11 +2 +15 +3 +3 +2 +2 +11 +2 +2 +16 +2 +9 +3 +3 +2 +2 +3 +13 +7 +3 +2 +2 +12 +6 +2 +2 +3 +2 +7 +2 +20 +4 +2 +2 +2 +13 +11 +3 +11 +2 +8 +2 +14 +12 +2 +2 +3 +2 +21 +3 +12 +2 +26 +3 +9 +2 +2 +2 +-1 +8 +3 +6 +2 +2 +9 +28 +2 +3 +2 +30 +2 +5 +2 +3 +2 +-1 +3 +15 +6 +16 +2 +10 +2 +2 +2 +2 +2 +2 +4 +2 +5 +12 +3 +3 +2 +2 +2 +6 +2 +13 +2 +2 +12 +2 +2 +12 +3 +14 +2 +11 +2 +2 +2 +4 +2 +2 +2 +3 +11 +2 +2 +3 +19 +2 +3 +4 +2 +3 +2 +2 +2 +13 +3 +3 +14 +2 +2 +2 +12 +2 +14 +2 +3 +2 +2 +2 +14 +3 +3 +3 +2 +3 +6 +2 +2 +6 +8 +2 +20 +2 +9 +2 +3 +3 +21 +13 +2 +5 +6 +2 +5 +2 +2 +3 +2 +2 +9 +2 +14 +3 +2 +2 +3 +6 +5 +18 +2 +3 +2 +2 +3 +2 +2 +13 +12 +2 +2 +2 +2 +3 +2 +2 +19 +15 +4 +2 +2 +3 +10 +2 +2 +2 +3 +18 +7 +2 +2 +8 +2 +2 +2 +7 +2 +11 +2 +2 +10 +9 +-1 +7 +2 +2 +3 +2 +3 +2 +2 +4 +2 +8 +2 +8 +2 +15 +2 +2 +2 +2 +2 +2 +3 +2 +2 +2 +8 +2 +13 +2 +2 +2 +3 +6 +2 +16 +10 +11 +5 +2 +2 +2 +2 +9 +2 +22 +3 +2 +13 +3 +2 +2 +24 +19 +2 +2 +2 +2 +16 +2 +3 +3 +2 +21 +2 +3 +8 +4 +3 +2 +2 +3 +3 +2 +2 +2 +3 +2 +2 +19 +11 +2 +17 +2 +5 +2 +2 +9 +2 +3 +3 +2 +2 +2 +20 +16 +8 +7 +2 +2 +4 +2 +2 +3 +2 +2 +8 +8 +2 +2 +2 +2 +2 +12 +3 +2 +2 +2 +15 +-1 +2 +2 +2 +11 +20 +2 +40 +2 +9 +14 +9 +2 +2 +2 +21 +2 +-1 +4 +2 +2 +2 +3 +3 +2 +3 +2 +2 +5 +3 +2 +2 +3 +2 +3 +2 +5 +2 +2 +3 +2 +12 +3 +4 +2 +2 +2 +15 +2 +2 +2 +2 +-1 +12 +4 +3 +2 +10 +2 +11 +3 +2 +2 +2 +2 +2 +3 +4 +2 +11 +2 +2 +2 +16 +2 +18 +16 +2 +3 +3 +2 +2 +3 +3 +3 +12 +2 +10 +10 +2 +2 +2 +2 +21 +28 +2 +2 +2 +13 +20 +5 +12 +18 +2 +2 +2 +2 +17 +2 +2 +18 +2 +10 +2 +3 +12 +5 +19 +2 +2 +13 +2 +2 +3 +2 +2 +2 +2 +2 +8 +2 +2 +3 +10 +2 +7 +2 +2 +2 +14 +2 +2 +6 +2 +2 +3 +2 +15 +2 +2 +5 +2 +7 +3 +2 +2 +2 +11 +13 +20 +2 +2 +2 +2 +2 +3 +11 +2 +3 +2 +2 +2 +2 +2 +2 +2 +7 +3 +2 +2 +2 +16 +2 +13 +3 +10 +3 +2 +2 +22 +3 +3 +2 +2 +7 +2 +2 +2 +2 +23 +2 +9 +16 +3 +2 +7 +14 +2 +2 +2 +3 +2 +10 +2 +12 +5 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +9 +9 +3 +14 +2 +11 +3 +3 +2 +2 +2 +4 +2 +2 +5 +2 +3 +9 +2 +2 +15 +7 +2 +2 +12 +3 +2 +2 +3 +2 +17 +2 +2 +2 +2 +3 +14 +3 +18 +15 +3 +14 +2 +6 +15 +2 +2 +2 +2 +-1 +2 +10 +2 +-1 +2 +37 +22 +4 +-1 +2 +2 +3 +6 +3 +2 +2 +30 +2 +2 +3 +2 +2 +2 +2 +32 +2 +2 +22 +2 +3 +3 +2 +3 +4 +2 +2 +12 +3 +2 +9 +2 +9 +2 +2 +2 +12 +15 +2 +2 +2 +3 +2 +3 +2 +6 +4 +2 +2 +13 +8 +5 +2 +2 +2 +2 +3 +3 +2 +2 +2 +23 +3 +3 +2 +3 +2 +3 +3 +3 +2 +2 +2 +6 +2 +2 +2 +3 +2 +2 +2 +2 +2 +3 +8 +8 +15 +2 +2 +12 +15 +3 +2 +2 +17 +2 +3 +2 +3 +3 +2 +2 +19 +7 +3 +17 +6 +2 +2 +2 +2 +2 +2 +4 +3 +16 +2 +2 +2 +2 +2 +2 +16 +3 +11 +2 +2 +8 +19 +3 +2 +3 +12 +2 +2 +2 +2 +4 +3 +2 +2 +2 +2 +3 +6 +2 +2 +2 +2 +3 +10 +2 +7 +12 +2 +2 +11 +2 +11 +2 +2 +3 +2 +16 +2 +10 +2 +12 +2 +2 +17 +2 +2 +4 +2 +2 +6 +3 +2 +3 +2 +2 +3 +2 +12 +13 +2 +2 +16 +2 +2 +2 +2 +9 +6 +3 +2 +12 +-1 +2 +2 +2 +2 +10 +2 +3 +2 +22 +2 +2 +2 +11 +2 +2 +12 +2 +2 +3 +2 +2 +2 +3 +3 +2 +7 +30 +19 +3 +2 +3 +13 +2 +2 +21 +3 +3 +2 +7 +2 +3 +23 +10 +2 +3 +3 +2 +2 +2 +2 +3 +2 +3 +6 +3 +2 +2 +2 +14 +2 +2 +2 +2 +4 +2 +3 +2 +2 +2 +3 +2 +2 +2 +3 +3 +2 +2 +2 +20 +2 +2 +3 +2 +2 +9 +2 +17 +2 +2 +3 +11 +3 +11 +2 +2 +2 +2 +2 +2 +4 +2 +3 +2 +2 +11 +3 +2 +4 +22 +2 +2 +3 +4 +11 +2 +2 +16 +17 +18 +7 +6 +3 +2 +3 +2 +3 +2 +2 +3 +25 +2 +3 +10 +2 +12 +2 +7 +12 +3 +2 +5 +2 +5 +2 +2 +10 +2 +2 +17 +3 +2 +5 +10 +16 +3 +2 +12 +2 +2 +2 +19 +3 +2 +18 +11 +6 +2 +2 +2 +2 +3 +2 +3 +2 +2 +2 +2 +2 +13 +2 +2 +2 +3 +2 +2 +2 +2 +15 +2 +3 +2 +2 +4 +8 +20 +2 +3 +4 +3 +17 +2 +13 +12 +5 +2 +2 +2 +2 +2 +3 +7 +13 +11 +2 +4 +10 +2 +2 +2 +3 +2 +24 +3 +2 +2 +7 +2 +3 +2 +2 +2 +2 +13 +2 +5 +3 +3 +2 +3 +2 +2 +9 +2 +2 +3 +13 +2 +2 +29 +20 +26 +3 +17 +2 +2 +13 +2 +7 +2 +2 +2 +2 +2 +3 +43 +2 +2 +26 +5 +3 +2 +14 +2 +2 +2 +16 +3 +2 +2 +12 +2 +2 +17 +2 +2 +2 +7 +2 +2 +6 +23 +3 +2 +2 +2 +3 +2 +2 +3 +7 +7 +2 +2 +3 +2 +22 +2 +2 +2 +11 +9 +8 +3 +2 +9 +2 +3 +2 +3 +2 +2 +3 +12 +2 +2 +2 +3 +13 +2 +2 +2 +2 +2 +17 +2 +2 +2 +26 +2 +2 +3 +2 +17 +2 +2 +2 +12 +3 +3 +4 +2 +3 +12 +12 +16 +6 +2 +3 +18 +2 +5 +2 +3 +6 +3 +3 +13 +3 +2 +14 +2 +2 +2 +4 +3 +2 +2 +2 +15 +19 +2 +2 +3 +37 +3 +2 +2 +2 +17 +10 +2 +8 +-1 +2 +16 +2 +10 +2 +39 +-1 +2 +2 +2 +2 +2 +10 +2 +2 +2 +12 +27 +18 +2 +2 +2 +8 +2 +2 +9 +2 +2 +4 +9 +14 +2 +2 +2 +9 +2 +2 +2 +2 +3 +2 +2 +2 +15 +13 +3 +2 +4 +2 +2 +10 +3 +2 +15 +2 +17 +2 +2 +2 +2 +3 +10 +2 +2 +4 +2 +2 +2 +6 +2 +2 +2 +3 +3 +-1 +2 +2 +-1 +2 +3 +5 +2 +9 +14 +9 +2 +11 +3 +3 +2 +2 +8 +9 +2 +2 +2 +2 +2 +2 +2 +2 +10 +19 +17 +3 +2 +2 +3 +2 +2 +2 +2 +10 +3 +2 +2 +3 +3 +10 +2 +19 +2 +3 +2 +2 +2 +2 +2 +9 +10 +2 +2 +3 +2 +2 +2 +-1 +2 +2 +3 +2 +2 +2 +10 +8 +15 +12 +2 +2 +11 +15 +2 +2 +2 +3 +3 +3 +2 +2 +15 +2 +3 +3 +3 +2 +2 +3 +11 +8 +2 +9 +2 +2 +15 +2 +3 +2 +2 +2 +2 +12 +2 +3 +-1 +17 +9 +3 +2 +2 +2 +2 +4 +2 +2 +2 +10 +7 +13 +2 +2 +13 +2 +9 +2 +2 +26 +2 +5 +3 +2 +2 +8 +2 +3 +2 +3 +3 +9 +10 +3 +13 +2 +3 +2 +2 +3 +15 +2 +2 +15 +2 +2 +16 +15 +3 +2 +2 +3 +7 +2 +2 +3 +2 +2 +2 +2 +2 +2 +2 +28 +2 +2 +2 +2 +2 +28 +2 +2 +2 +8 +7 +3 +2 +9 +3 +2 +44 +16 +2 +2 +2 +2 +4 +2 +2 +2 +9 +33 +2 +2 +2 +3 +2 +2 +2 +2 +2 +12 +2 +2 +10 +2 +2 +2 +3 +2 +2 +3 +13 +4 +2 +19 +2 +13 +2 +3 +2 +6 +11 +15 +2 +2 +6 +2 +23 +5 +2 +2 +3 +17 +9 +2 +2 +2 +13 +13 +2 +2 +2 +3 +3 +2 +8 +2 +3 +16 +2 +2 +11 +2 +7 +2 +10 +6 +3 +2 +2 +2 +2 +2 +14 +2 +3 +4 +14 +2 +2 +3 +4 +8 +2 +2 +4 +3 +3 +18 +10 +14 +11 +5 +2 +3 +2 +18 +3 +12 +3 +2 +2 +9 +10 +2 +2 +12 +2 +2 +2 +2 +3 +2 +3 +2 +4 +2 +5 +2 +2 +3 +3 +2 +28 +2 +2 +3 +3 +2 +2 +27 +2 +2 +17 +2 +3 +2 +15 +13 +3 +3 +2 +9 +2 +2 +2 +2 +2 +8 +16 +12 +17 +4 +4 +2 +2 +11 +2 +3 +3 +2 +2 +3 +2 +2 +2 +2 +2 +2 +9 +2 +11 +2 +2 +9 +2 +2 +3 +14 +2 +13 +2 +9 +3 +2 +2 +2 +2 +2 +13 +2 +2 +2 +2 +2 +6 +3 +2 +2 +3 +2 +6 +2 +8 +10 +3 +2 +5 +3 +2 +3 +2 +2 +2 +6 +8 +2 +2 +2 +2 +2 +2 +8 +2 +2 +20 +2 +20 +3 +2 +5 +2 +3 +2 +2 +2 +3 +2 +2 +2 +2 +5 +2 +2 +5 +3 +15 +2 +2 +13 +3 +12 +8 +12 +3 +2 +2 +2 +5 +2 +3 +2 +18 +16 +2 +2 +2 +3 +6 +12 +4 +2 +2 +2 +2 +17 +26 +2 +11 +22 +2 +2 +2 +22 +3 +2 +17 +10 +2 +2 +3 +3 +23 +2 +-1 +23 +8 +2 +2 +3 +11 +3 +5 +2 +13 +2 +3 +2 +2 +9 +3 +3 +2 +2 +2 +2 +3 +2 +2 +5 +2 +2 +2 +2 +16 +3 +2 +2 +2 +12 +2 +3 +15 +2 +10 +2 +2 +5 +2 +2 +2 +2 +2 +3 +3 +2 +3 +2 +2 +22 +3 +2 +3 +2 +2 +2 +18 +2 +2 +2 +11 +2 +2 +2 +3 +2 +9 +5 +13 +3 +2 +2 +3 +2 +14 +3 +2 +2 +16 +3 +6 +3 +3 +2 +2 +4 +-1 +13 +2 +15 +2 +2 +3 +2 +17 +15 +9 +9 +2 +2 +2 +9 +3 +2 +14 +42 +20 +15 +19 +6 +12 +2 +9 +2 +2 +3 +2 +2 +2 +2 +13 +3 +2 +2 +2 +2 +2 +2 +3 +17 +10 +15 +2 +3 +20 +2 +2 +13 +3 +3 +2 +2 +3 +3 +3 +2 +2 +3 +2 +2 +3 +2 +13 +2 +2 +2 +15 +12 +17 +3 +3 +2 +3 +2 +3 +13 +10 +5 +3 +3 +21 +2 +2 +2 +2 +2 +32 +19 +3 +2 +2 +2 +3 +2 +2 +5 +4 +2 +2 +2 +6 +3 +3 +2 +2 +3 +2 +2 +3 +2 +5 +3 +3 +2 +2 +9 +3 +17 +13 +3 +3 +2 +2 +7 +2 +2 +14 +15 +2 +2 +2 +3 +5 +2 +2 +2 +2 +2 +11 +2 +21 +2 +9 +8 +2 +2 +2 +2 +2 +30 +3 +2 +18 +3 +24 +3 +2 +9 +2 +2 +2 +3 +4 +3 +9 +2 +3 +2 +2 +11 +2 +9 +12 +8 +13 +4 +3 +2 +2 +2 +15 +20 +27 +3 +11 +13 +10 +2 +2 +11 +3 +3 +2 +19 +2 +8 +4 +3 +15 +7 +3 +4 +2 +3 +13 +2 +3 +2 +3 +9 +2 +13 +2 +2 +16 +17 +12 +4 +3 +2 +2 +3 +3 +3 +10 +11 +4 +2 +11 +11 +2 +7 +2 +2 +4 +2 +2 +2 +7 +2 +7 +2 +2 +3 +16 +2 +12 +2 +22 +2 +3 +3 +2 +3 +6 +2 +2 +2 +3 +14 +25 +2 +25 +4 +15 +3 +2 +19 +2 +10 +12 +2 +2 +2 +2 +3 +2 +9 +2 +5 +13 +10 +2 +14 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +12 +2 +2 +2 +13 +3 +3 +3 +2 +6 +2 +2 +3 +3 +3 +2 +2 +15 +14 +10 +2 +2 +2 +2 +2 +5 +2 +8 +3 +3 +2 +3 +10 +3 +3 +11 +2 +2 +2 +2 +2 +12 +2 +2 +3 +18 +2 +2 +12 +3 +2 +2 +9 +8 +2 +2 +2 +2 +14 +3 +3 +2 +12 +2 +2 +14 +8 +7 +16 +2 +8 +2 +2 +3 +2 +14 +3 +2 +3 +3 +3 +2 +2 +2 +9 +20 +2 +10 +3 +17 +12 +2 +3 +15 +3 +2 +16 +2 +3 +8 +2 +2 +4 +15 +2 +3 +2 +3 +2 +2 +2 +15 +2 +12 +2 +3 +12 +2 +3 +3 +2 +13 +2 +2 +2 +2 +2 +7 +11 +2 +8 +12 +2 +3 +2 +2 +2 +21 +2 +3 +2 +2 +7 +2 +2 +-1 +2 +2 +3 +2 +2 +2 +2 +11 +3 +11 +3 +25 +10 +8 +2 +3 +5 +2 +2 +14 +3 +2 +11 +8 +8 +5 +2 +2 +7 +2 +2 +2 +17 +2 +4 +2 +3 +2 +11 +8 +2 +3 +2 +26 +11 +2 +20 +2 +3 +17 +11 +2 +8 +3 +2 +10 +6 +17 +16 +3 +2 +2 +17 +2 +3 +2 +3 +2 +2 +2 +3 +2 +5 +2 +2 +2 +10 +2 +2 +3 +3 +2 +16 +9 +3 +2 +12 +11 +2 +10 +2 +22 +2 +3 +3 +14 +2 +2 +12 +-1 +13 +2 +2 +2 +19 +2 +14 +21 +3 +15 +2 +6 +3 +2 +2 +2 +9 +-1 +5 +2 +2 +2 +3 +2 +8 +2 +2 +2 +4 +2 +2 +13 +8 +2 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +20 +9 +4 +3 +14 +2 +2 +5 +2 +2 +3 +13 +3 +2 +9 +2 +16 +20 +2 +3 +2 +2 +3 +2 +3 +2 +2 +3 +-1 +2 +2 +20 +10 +12 +2 +23 +3 +2 +3 +2 +5 +29 +2 +17 +2 +2 +2 +20 +23 +8 +2 +2 +10 +6 +2 +2 +16 +17 +7 +2 +14 +32 +3 +3 +2 +11 +7 +2 +18 +2 +7 +16 +8 +2 +3 +2 +2 +2 +7 +9 +3 +8 +2 +13 +2 +23 +3 +2 +8 +3 +3 +6 +2 +2 +2 +4 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +13 +2 +26 +5 +3 +2 +3 +2 +2 +3 +2 +3 +8 +2 +16 +18 +2 +2 +2 +21 +2 +3 +2 +3 +2 +2 +12 +3 +2 +17 +3 +2 +3 +3 +2 +13 +2 +2 +3 +3 +3 +2 +2 +16 +2 +10 +3 +2 +2 +19 +4 +3 +3 +26 +2 +21 +2 +2 +2 +2 +3 +2 +2 +2 +3 +3 +2 +3 +14 +4 +3 +8 +4 +2 +3 +2 +2 +2 +2 +2 +2 +2 +3 +2 +2 +3 +2 +7 +2 +16 +2 +2 +2 +2 +2 +2 +3 +2 +3 +19 +2 +3 +2 +3 +2 +3 +2 +-1 +3 +3 +3 +10 +2 +2 +2 +3 +5 +2 +5 +13 +2 +3 +3 +21 +5 +3 +2 +2 +3 +6 +3 +2 +10 +2 +9 +2 +2 +2 +14 +33 +6 +9 +2 +3 +18 +3 +2 +2 +10 +2 +2 +2 +3 +2 +11 +12 +12 +3 +10 +2 +2 +4 +3 +29 +28 +2 +11 +3 +17 +2 +2 +18 +11 +2 +2 +2 +14 +2 +15 +2 +8 +7 +20 +2 +3 +3 +2 +3 +11 +2 +3 +3 +13 +2 +7 +2 +2 +3 +2 +9 +11 +2 +2 +2 +3 +2 +5 +3 +2 +2 +2 +2 +2 +3 +2 +2 +14 +3 +2 +3 +2 +2 +2 +2 +9 +24 +2 +3 +2 +12 +2 +2 +2 +3 +14 +2 +2 +6 +2 +2 +13 +3 +3 +2 +2 +2 +12 +10 +7 +13 +2 +2 +2 +32 +6 +10 +9 +2 +2 +2 +9 +9 +2 +5 +23 +29 +11 +2 +2 +29 +2 +15 +2 +10 +2 +2 +4 +2 +3 +4 +3 +2 +8 +-1 +2 +2 +13 +2 +2 +2 +2 +2 +2 +3 +2 +14 +2 +2 +9 +2 +6 +2 +2 +12 +4 +2 +2 +2 +13 +4 +3 +6 +12 +2 +3 +2 +2 +9 +2 +3 +3 +2 +16 +10 +2 +15 +2 +2 +7 +2 +3 +2 +2 +2 +11 +2 +2 +2 +24 +13 +28 +3 +2 +2 +3 +8 +2 +2 +5 +9 +2 +2 +3 +2 +2 +2 +2 +3 +-1 +2 +16 +2 +11 +3 +2 +3 +3 +2 +3 +2 +18 +2 +2 +2 +9 +2 +2 +2 +5 +8 +17 +22 +2 +3 +3 +3 +2 +2 +2 +13 +2 +2 +3 +15 +10 +2 +11 +2 +2 +2 +2 +3 +2 +11 +19 +3 +2 +2 +2 +11 +2 +20 +22 +2 +3 +14 +3 +3 +15 +2 +2 +7 +3 +3 +2 +2 +3 +2 +2 +3 +7 +2 +2 +11 +2 +3 +15 +2 +2 +2 +3 +2 +20 +2 +2 +13 +11 +7 +12 +2 +13 +47 +2 +7 +2 +3 +2 +2 +9 +10 +3 +3 +2 +8 +7 +2 +2 +5 +2 +3 +2 +12 +13 +2 +13 +2 +2 +6 +2 +13 +3 +2 +2 +4 +12 +2 +2 +2 +2 +2 +14 +2 +2 +3 +11 +7 +3 +3 +7 +3 +3 +10 +2 +19 +2 +2 +4 +2 +2 +2 +28 +2 +2 +3 +3 +2 +2 +-1 +2 +2 +2 +5 +2 +2 +12 +2 +2 +3 +3 +2 +-1 +3 +3 +2 +2 +3 +2 +2 +2 +5 +3 +13 +3 +9 +3 +3 +3 +2 +2 +2 +7 +2 +4 +2 +2 +9 +9 +2 +7 +2 +11 +2 +3 +2 +3 +2 +2 +8 +2 +-1 +2 +4 +2 +3 +19 +3 +2 +2 +3 +2 +4 +3 +3 +3 +2 +2 +10 +2 +2 +9 +2 +10 +2 +2 +14 +2 +2 +2 +2 +3 +2 +4 +2 +2 +14 +2 +3 +2 +11 +11 +2 +5 +14 +2 +2 +2 +5 +10 +3 +8 +4 +5 +18 +2 +15 +2 +10 +2 +2 +2 +3 +2 +16 +2 +2 +3 +15 +2 +2 +2 +2 +5 +2 +5 +2 +3 +3 +15 +2 +2 +2 +2 +7 +2 +2 +2 +8 +2 +2 +5 +2 +20 +2 +2 +10 +2 +15 +7 +2 +3 +2 +3 +4 +2 +10 +3 +8 +2 +2 +11 +2 +6 +2 +2 +2 +2 +3 +2 +11 +2 +2 +2 +2 +2 +9 +13 +2 +3 +2 +2 +2 +3 +3 +2 +3 +11 +2 +2 +12 +11 +2 +19 +3 +4 +5 +2 +12 +3 +2 +40 +3 +2 +2 +2 +2 +2 +9 +2 +2 +2 +-1 +2 +2 +15 +2 +2 +14 +14 +2 +2 +2 +5 +8 +3 +4 +2 +2 +2 +2 +3 +3 +2 +2 +3 +11 +9 +3 +2 +2 +3 +3 +2 +2 +2 +13 +2 +2 +9 +19 +2 +2 +2 +13 +2 +14 +3 +2 +2 +2 +3 +2 +2 +2 +2 +14 +2 +2 +2 +2 +2 +2 +5 +3 +2 +2 +2 +2 +2 +2 +2 +17 +2 +3 +14 +2 +2 +3 +-1 +10 +18 +5 +2 +2 +2 +2 +3 +2 +2 +3 +2 +2 +2 +2 +2 +13 +2 +5 +2 +5 +2 +2 +2 +2 +6 +2 +19 +2 +2 +2 +2 +2 +3 +11 +3 +2 +2 +3 +2 +5 +2 +2 +19 +2 +6 +5 +5 +12 +2 +10 +9 +11 +2 +8 +15 +7 +2 +2 +2 +2 +2 +2 +2 +17 +15 +2 +17 +3 +3 +12 +2 +2 +10 +10 +3 +2 +2 +2 +2 +7 +2 +2 +9 +10 +3 +3 +2 +2 +2 +3 +2 +9 +2 +4 +17 +12 +2 +2 +2 +2 +7 +3 +2 +2 +3 +2 +2 +2 +9 +2 +2 +4 +15 +2 +2 +2 +2 +16 +16 +7 +4 +2 +13 +2 +2 +3 +2 +2 +4 +19 +2 +2 +6 +2 +2 +2 +2 +2 +3 +23 +2 +8 +17 +2 +7 +6 +2 +3 +18 +2 +2 +2 +3 +2 +3 +2 +15 +2 +2 +2 +2 +4 +2 +5 +3 +2 +15 +21 +5 +2 +15 +3 +2 +2 +4 +2 +2 +15 +3 +2 +3 +9 +2 +3 +6 +2 +6 +3 +2 +-1 +2 +3 +2 +2 +2 +18 +2 +2 +12 +3 +2 +2 +6 +2 +10 +2 +13 +48 +2 +2 +12 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +11 +2 +2 +12 +6 +2 +2 +4 +2 +9 +5 +10 +2 +2 +2 +12 +2 +3 +24 +3 +12 +2 +2 +18 +3 +3 +3 +2 +2 +4 +2 +3 +2 +9 +21 +8 +9 +2 +7 +2 +8 +2 +3 +16 +13 +2 +9 +7 +2 +2 +17 +2 +2 +3 +2 +2 +3 +2 +2 +2 +2 +2 +2 +19 +16 +2 +6 +7 +12 +3 +3 +2 +3 +15 +2 +14 +2 +5 +10 +7 +7 +14 +2 +2 +2 +3 +3 +2 +9 +3 +13 +2 +3 +2 +3 +2 +15 +2 +2 +2 +2 +7 +2 +2 +20 +3 +2 +13 +2 +2 +2 +2 +2 +2 +2 +2 +10 +2 +3 +2 +3 +28 +2 +2 +3 +2 +7 +2 +3 +2 +2 +20 +2 +2 +2 +2 +2 +2 +3 +2 +2 +3 +3 +15 +2 +2 +2 +2 +19 +3 +3 +11 +2 +2 +2 +3 +5 +2 +2 +16 +2 +2 +2 +2 +3 +2 +9 +24 +12 +3 +3 +16 +2 +2 +7 +2 +7 +2 +2 +2 +2 +2 +2 +4 +2 +2 +2 +2 +2 +17 +2 +2 +11 +14 +3 +2 +3 +3 +3 +3 +2 +2 +11 +3 +15 +4 +3 +2 +2 +18 +8 +2 +17 +2 +11 +3 +2 +2 +2 +2 +2 +25 +2 +2 +15 +2 +2 +2 +2 +2 +15 +3 +2 +11 +2 +2 +2 +3 +4 +2 +2 +15 +2 +11 +2 +15 +2 +2 +2 +2 +3 +2 +3 +2 +2 +5 +11 +2 +2 +2 +9 +16 +10 +3 +2 +22 +18 +3 +2 +5 +3 +2 +2 +4 +2 +13 +2 +3 +2 +2 +2 +2 +10 +2 +3 +2 +2 +2 +2 +10 +3 +2 +2 +3 +20 +3 +3 +21 +13 +2 +3 +2 +2 +10 +7 +2 +2 +2 +5 +2 +2 +14 +2 +9 +2 +2 +16 +3 +3 +2 +3 +2 +2 +5 +2 +2 +2 +2 +3 +11 +3 +2 +10 +13 +14 +2 +2 +2 +3 +2 +15 +3 +2 +3 +2 +2 +3 +18 +2 +2 +12 +13 +12 +10 +2 +3 +2 +5 +3 +9 +2 +3 +3 +3 +2 +2 +2 +2 +11 +2 +2 +2 +10 +2 +2 +12 +13 +2 +2 +31 +6 +16 +2 +2 +2 +2 +2 +14 +11 +2 +2 +24 +4 +12 +2 +2 +2 +2 +13 +2 +2 +2 +2 +20 +2 +19 +8 +6 +2 +17 +2 +2 +2 +3 +4 +2 +2 +2 +2 +2 +2 +2 +3 +2 +32 +2 +2 +3 +13 +3 +2 +2 +2 +3 +2 +3 +2 +2 +2 +2 +3 +2 +2 +2 +2 +2 +2 +2 +2 +9 +2 +8 +2 +5 +2 +9 +2 +2 +2 +4 +2 +2 +23 +2 +14 +2 +2 +2 +2 +2 +2 +2 +3 +9 +16 +16 +2 +2 +3 +14 +2 +10 +15 +2 +2 +2 +2 +3 +2 +17 +2 +3 +2 +2 +2 +2 +2 +6 +48 +12 +2 +2 +2 +3 +2 +9 +2 +2 +3 +2 +7 +3 +2 +2 +10 +12 +3 +2 +2 +2 +2 +5 +15 +18 +2 +2 +12 +3 +17 +2 +7 +3 +19 +3 +3 +6 +3 +2 +2 +3 +2 +2 +22 +3 +2 +7 +2 +2 +13 +16 +18 +2 +2 +7 +9 +4 +2 +2 +11 +2 +3 +2 +4 +3 +3 +2 +2 +2 +10 +3 +3 +3 +25 +3 +3 +2 +2 +3 +2 +2 +13 +3 +18 +2 +5 +2 +2 +4 +3 +9 +2 +11 +10 +2 +18 +3 +2 +3 +2 +9 +2 +15 +2 +2 +3 +2 +2 +2 +2 +2 +17 +9 +4 +10 +2 +3 +16 +2 +2 +2 +13 +2 +2 +4 +22 +2 +23 +2 +2 +26 +3 +2 +8 +2 +12 +2 +3 +2 +15 +3 +2 +2 +12 +2 +2 +2 +2 +2 +2 +2 +2 +3 +2 +3 +2 +2 +2 +19 +15 +2 +3 +2 +20 +2 +3 +3 +2 +3 +7 +36 +2 +2 +2 +2 +16 +4 +2 +3 +2 +2 +2 +2 +2 +2 +3 +3 +13 +3 +2 +4 +2 +2 +2 +22 +2 +2 +2 +3 +3 +2 +3 +2 +2 +2 +2 +2 +2 +15 +2 +2 +2 +18 +21 +9 +2 +2 +2 +2 +6 +15 +2 +2 +2 +6 +2 +2 +4 +9 +3 +9 +2 +2 +3 +2 +2 +19 +2 +2 +2 +2 +2 +2 +6 +2 +2 +9 +2 +2 +2 +2 +2 +2 +23 +2 +8 +2 +3 +12 +2 +2 +3 +3 +2 +2 +15 +2 +2 +15 +7 +2 +3 +2 +2 +2 +5 +9 +2 +2 +3 +2 +4 +2 +2 +3 +2 +2 +9 +7 +2 +2 +19 +9 +-1 +3 +3 +20 +2 +3 +2 +2 +3 +5 +3 +9 +2 +3 +6 +14 +2 +2 +2 +6 +2 +2 +2 +20 +15 +7 +2 +10 +13 +17 +3 +3 +2 +2 +32 +2 +2 +25 +2 +2 +3 +2 +20 +3 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +20 +2 +10 +10 +2 +3 +2 +2 +2 +2 +4 +6 +2 +2 +3 +2 +2 +2 +31 +2 +2 +3 +2 +2 +2 +6 +2 +5 +2 +6 +2 +2 +5 +3 +3 +2 +2 +2 +2 +3 +2 +2 +2 +11 +10 +3 +18 +6 +2 +4 +30 +2 +9 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +9 +2 +3 +2 +2 +10 +8 +15 +9 +2 +14 +3 +2 +6 +10 +2 +2 +2 +20 +2 +2 +3 +2 +2 +13 +2 +2 +3 +2 +24 +2 +3 +15 +2 +3 +3 +3 +2 +2 +8 +9 +2 +2 +2 +15 +2 +3 +3 +2 +2 +2 +3 +2 +2 +2 +2 +2 +3 +2 +2 +2 +9 +2 +3 +2 +2 +2 +2 +2 +3 +3 +2 +21 +2 +3 +11 +24 +3 +2 +2 +3 +2 +3 +2 +2 +2 +2 +2 +2 +2 +2 +8 +12 +2 +14 +2 +9 +4 +3 +2 +25 +14 +2 +2 +8 +2 +3 +6 +2 +12 +2 +8 +2 +2 +5 +2 +2 +14 +2 +9 +2 +11 +5 +2 +13 +8 +2 +3 +2 +2 +22 +2 +10 +2 +3 +2 +2 +19 +2 +3 +2 +2 +2 +3 +11 +9 +2 +3 +3 +8 +2 +15 +15 +3 +2 +2 +2 +36 +3 +2 +2 +2 +2 +11 +6 +2 +2 +2 +2 +2 +3 +2 +2 +18 +2 +2 +2 +3 +2 +2 +2 +3 +32 +3 +2 +2 +2 +3 +2 +13 +2 +2 +3 +15 +4 +2 +16 +2 +2 +3 +2 +8 +2 +3 +2 +2 +3 +2 +4 +2 +4 +2 +23 +6 +3 +4 +2 +2 +2 +2 +2 +9 +2 +9 +5 +2 +8 +2 +2 +2 +6 +2 +5 +2 +3 +2 +2 +2 +9 +2 +2 +2 +2 +3 +2 +2 +3 +2 +2 +3 +2 +12 +11 +2 +2 +19 +3 +8 +2 +2 +2 +3 +2 +16 +2 +11 +2 +2 +9 +2 +9 +2 +3 +2 +2 +2 +3 +5 +2 +2 +5 +2 +2 +2 +16 +2 +3 +2 +13 +2 +2 +2 +2 +11 +2 +2 +2 +19 +8 +7 +9 +3 +2 +2 +17 +2 +3 +2 +4 +2 +3 +2 +12 +2 +2 +16 +2 +2 +3 +2 +2 +14 +20 +4 +5 +18 +3 +9 +2 +2 +5 +2 +2 +2 +4 +2 +10 +10 +2 +2 +11 +2 +2 +3 +14 +2 +13 +14 +2 +3 +5 +3 +2 +2 +2 +11 +2 +4 +2 +3 +2 +3 +18 +5 +2 +2 +3 +3 +10 +18 +2 +2 +2 +2 +8 +12 +2 +5 +2 +2 +3 +2 +2 +13 +2 +2 +3 +2 +19 +2 +2 +21 +12 +7 +2 +3 +2 +12 +2 +3 +2 +9 +7 +2 +2 +3 +2 +2 +7 +2 +26 +30 +14 +3 +3 +10 +3 +3 +9 +7 +2 +2 +12 +8 +3 +2 +2 +3 +2 +5 +14 +13 +2 +3 +13 +9 +8 +2 +24 +2 +3 +7 +15 +19 +18 +3 +15 +2 +2 +2 +2 +9 +2 +2 +14 +2 +2 +2 +2 +2 +2 +2 +16 +2 +2 +4 +2 +2 +17 +2 +2 +13 +9 +2 +2 +2 +2 +3 +2 +3 +8 +2 +3 +2 +17 +2 +3 +2 +2 +3 +2 +2 +2 +2 +2 +2 +3 +9 +8 +3 +2 +10 +3 +2 +12 +2 +2 +2 +18 +4 +2 +13 +3 +2 +3 +2 +16 +9 +2 +2 +3 +3 +5 +2 +2 +5 +5 +13 +2 +2 +9 +10 +2 +3 +2 +2 +2 +17 +2 +3 +10 +8 +2 +3 +2 +14 +2 +3 +7 +2 +2 +14 +2 +3 +3 +11 +2 +2 +2 +7 +7 +3 +2 +2 +2 +2 +3 +2 +3 +2 +4 +14 +6 +3 +3 +2 +2 +-1 +2 +21 +17 +3 +25 +2 +6 +2 +2 +2 +2 +2 +2 +2 +3 +3 +2 +2 +12 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_1.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_1.txt new file mode 100644 index 0000000..24b000b --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_1.txt @@ -0,0 +1,100 @@ +54 +72 +124 +175 +70 +267 +295 +396 +365 +132 +312 +381 +252 +359 +210 +489 +160 +185 +177 +-1 +-1 +443 +-1 +255 +147 +141 +-1 +121 +-1 +119 +-1 +139 +140 +-1 +-1 +122 +535 +258 +36 +-1 +-1 +171 +523 +161 +-1 +534 +204 +-1 +197 +-1 +326 +54 +111 +72 +90 +-1 +187 +-1 +243 +174 +484 +136 +-1 +176 +590 +583 +204 +171 +227 +143 +110 +242 +165 +240 +585 +152 +251 +449 +343 +234 +67 +289 +322 +161 +-1 +502 +77 +98 +39 +503 +175 +358 +-1 +43 +56 +206 +368 +-1 +324 +352 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_10.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_10.txt new file mode 100644 index 0000000..ea6d8b1 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_10.txt @@ -0,0 +1,100 @@ +57 +113 +121 +142 +178 +62 +190 +275 +149 +185 +205 +500 +391 +242 +21 +148 +105 +-1 +189 +23 +-1 +-1 +78 +175 +189 +152 +438 +236 +84 +424 +56 +14 +223 +130 +-1 +108 +-1 +123 +63 +118 +118 +-1 +320 +336 +34 +35 +112 +75 +-1 +32 +34 +45 +43 +21 +29 +165 +40 +463 +160 +273 +440 +95 +293 +165 +472 +243 +52 +219 +120 +36 +81 +49 +64 +150 +-1 +107 +59 +45 +252 +-1 +-1 +70 +-1 +116 +80 +113 +118 +78 +81 +46 +205 +121 +303 +109 +355 +65 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_11.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_11.txt new file mode 100644 index 0000000..6785cc9 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_11.txt @@ -0,0 +1,100 @@ +36 +33 +99 +73 +187 +182 +62 +303 +89 +228 +199 +75 +61 +83 +84 +179 +308 +78 +-1 +161 +147 +103 +16 +34 +37 +115 +65 +148 +19 +95 +136 +187 +76 +122 +154 +40 +135 +125 +22 +-1 +152 +146 +222 +64 +49 +28 +36 +54 +343 +-1 +83 +41 +86 +114 +340 +163 +-1 +56 +185 +22 +142 +84 +593 +343 +92 +278 +71 +74 +131 +17 +38 +251 +-1 +353 +72 +227 +70 +83 +45 +234 +50 +225 +120 +38 +41 +293 +326 +515 +-1 +64 +300 +81 +123 +273 +21 +306 +-1 +142 +-1 +320 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_12.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_12.txt new file mode 100644 index 0000000..e459ee8 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_12.txt @@ -0,0 +1,100 @@ +16 +48 +29 +14 +191 +199 +29 +257 +341 +527 +345 +374 +87 +39 +-1 +257 +151 +-1 +-1 +63 +16 +22 +124 +257 +128 +-1 +201 +102 +114 +184 +30 +116 +47 +202 +214 +266 +224 +95 +31 +21 +97 +87 +203 +238 +141 +49 +-1 +60 +139 +25 +238 +18 +338 +185 +141 +272 +250 +184 +30 +153 +127 +98 +368 +23 +83 +44 +-1 +65 +-1 +15 +39 +238 +122 +46 +272 +23 +320 +32 +36 +73 +191 +199 +351 +223 +-1 +181 +109 +-1 +71 +91 +36 +139 +556 +69 +163 +216 +116 +-1 +538 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_13.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_13.txt new file mode 100644 index 0000000..23f92ce --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_13.txt @@ -0,0 +1,100 @@ +40 +62 +29 +83 +118 +85 +30 +110 +196 +299 +98 +50 +205 +328 +23 +21 +63 +238 +174 +546 +110 +84 +31 +235 +120 +146 +118 +20 +24 +61 +151 +56 +-1 +73 +133 +-1 +159 +45 +67 +283 +43 +-1 +38 +37 +17 +49 +-1 +96 +127 +55 +-1 +108 +489 +350 +138 +94 +172 +36 +167 +211 +15 +314 +242 +136 +140 +20 +-1 +317 +250 +241 +189 +-1 +454 +27 +596 +193 +215 +57 +137 +256 +184 +30 +186 +61 +37 +129 +145 +20 +165 +94 +226 +-1 +44 +128 +65 +-1 +78 +75 +386 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_14.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_14.txt new file mode 100644 index 0000000..c115a6f --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_14.txt @@ -0,0 +1,100 @@ +20 +30 +24 +50 +111 +32 +94 +15 +45 +248 +21 +140 +213 +291 +62 +39 +71 +119 +196 +59 +-1 +60 +50 +311 +52 +191 +-1 +-1 +80 +69 +-1 +-1 +26 +65 +127 +61 +163 +99 +197 +204 +-1 +163 +117 +98 +26 +37 +259 +95 +58 +278 +41 +23 +466 +71 +52 +23 +173 +175 +105 +28 +177 +-1 +75 +49 +41 +36 +183 +541 +192 +585 +23 +84 +105 +-1 +121 +210 +32 +32 +-1 +39 +33 +58 +80 +73 +174 +497 +263 +250 +78 +268 +97 +29 +180 +-1 +96 +115 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_15.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_15.txt new file mode 100644 index 0000000..2f845cf --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_15.txt @@ -0,0 +1,100 @@ +14 +16 +102 +-1 +-1 +60 +47 +-1 +-1 +-1 +89 +-1 +197 +256 +198 +280 +213 +283 +113 +280 +395 +-1 +-1 +357 +-1 +-1 +-1 +-1 +224 +-1 +257 +134 +64 +-1 +-1 +112 +-1 +84 +283 +-1 +-1 +-1 +-1 +34 +385 +165 +-1 +236 +-1 +39 +-1 +56 +-1 +189 +-1 +74 +116 +-1 +-1 +62 +-1 +61 +-1 +-1 +-1 +-1 +-1 +-1 +75 +238 +263 +59 +-1 +16 +-1 +-1 +243 +16 +198 +-1 +-1 +-1 +-1 +62 +517 +-1 +-1 +172 +49 +40 +-1 +35 +225 +-1 +23 +112 +-1 +425 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_16.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_16.txt new file mode 100644 index 0000000..f8eb369 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_16.txt @@ -0,0 +1,100 @@ +147 +201 +149 +200 +-1 +18 +498 +-1 +-1 +222 +86 +239 +-1 +101 +47 +201 +-1 +-1 +17 +-1 +-1 +-1 +49 +-1 +251 +68 +141 +472 +-1 +287 +149 +-1 +125 +445 +164 +17 +-1 +-1 +58 +-1 +397 +496 +90 +53 +-1 +-1 +34 +597 +-1 +264 +405 +239 +-1 +-1 +-1 +-1 +17 +46 +73 +97 +285 +124 +65 +306 +479 +213 +-1 +320 +183 +36 +-1 +29 +99 +26 +198 +221 +434 +152 +-1 +-1 +-1 +-1 +-1 +203 +185 +61 +-1 +70 +132 +392 +334 +56 +368 +162 +471 +-1 +511 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_17.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_17.txt new file mode 100644 index 0000000..4745351 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_17.txt @@ -0,0 +1,100 @@ +170 +288 +-1 +-1 +-1 +69 +-1 +-1 +-1 +275 +95 +355 +267 +263 +174 +-1 +249 +-1 +80 +400 +15 +-1 +141 +115 +43 +-1 +233 +65 +-1 +45 +-1 +476 +194 +-1 +-1 +109 +286 +-1 +-1 +14 +-1 +66 +-1 +228 +78 +-1 +356 +162 +-1 +60 +141 +-1 +-1 +37 +-1 +-1 +-1 +422 +264 +-1 +-1 +476 +-1 +-1 +213 +112 +-1 +99 +310 +538 +-1 +-1 +-1 +-1 +-1 +51 +376 +-1 +203 +125 +189 +185 +340 +50 +64 +16 +-1 +-1 +250 +117 +-1 +155 +34 +16 +18 +-1 +360 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_18.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_18.txt new file mode 100644 index 0000000..3470af0 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_18.txt @@ -0,0 +1,100 @@ +14 +71 +223 +73 +323 +451 +77 +-1 +-1 +-1 +17 +80 +-1 +167 +326 +15 +198 +151 +-1 +191 +200 +100 +164 +-1 +125 +-1 +-1 +-1 +-1 +181 +437 +-1 +244 +108 +-1 +303 +-1 +268 +-1 +122 +223 +285 +343 +101 +-1 +143 +-1 +84 +124 +170 +62 +143 +-1 +-1 +224 +91 +-1 +-1 +-1 +86 +-1 +-1 +52 +193 +-1 +-1 +81 +95 +-1 +33 +-1 +404 +291 +-1 +-1 +340 +14 +-1 +-1 +-1 +-1 +-1 +31 +-1 +-1 +255 +141 +-1 +52 +-1 +-1 +16 +472 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_19.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_19.txt new file mode 100644 index 0000000..aa51f21 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_19.txt @@ -0,0 +1,100 @@ +160 +292 +57 +212 +67 +83 +37 +434 +165 +342 +157 +-1 +-1 +139 +-1 +230 +403 +-1 +290 +56 +-1 +220 +419 +-1 +119 +-1 +281 +216 +355 +137 +-1 +305 +-1 +79 +424 +-1 +-1 +260 +81 +135 +-1 +136 +16 +54 +76 +297 +114 +-1 +-1 +-1 +49 +235 +-1 +154 +76 +-1 +571 +90 +-1 +194 +96 +120 +-1 +-1 +-1 +96 +-1 +31 +-1 +111 +349 +204 +-1 +-1 +-1 +-1 +274 +102 +38 +495 +197 +278 +-1 +-1 +-1 +447 +67 +-1 +-1 +-1 +87 +-1 +-1 +493 +-1 +211 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_2.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_2.txt new file mode 100644 index 0000000..5f72205 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_2.txt @@ -0,0 +1,100 @@ +34 +148 +175 +29 +87 +40 +277 +323 +305 +245 +233 +172 +51 +299 +-1 +183 +422 +173 +376 +52 +370 +15 +113 +-1 +156 +-1 +28 +98 +311 +92 +360 +208 +45 +197 +350 +-1 +266 +-1 +148 +158 +104 +52 +562 +274 +93 +115 +-1 +500 +257 +16 +262 +-1 +128 +-1 +474 +98 +-1 +-1 +-1 +77 +232 +-1 +82 +36 +141 +134 +75 +25 +206 +81 +-1 +-1 +-1 +286 +-1 +121 +-1 +78 +265 +114 +87 +236 +101 +-1 +190 +139 +151 +-1 +125 +90 +270 +-1 +115 +218 +-1 +534 +242 +319 +489 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_20.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_20.txt new file mode 100644 index 0000000..02eb352 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_20.txt @@ -0,0 +1,100 @@ +137 +114 +207 +184 +226 +147 +127 +140 +317 +328 +-1 +-1 +-1 +184 +53 +520 +-1 +137 +-1 +262 +188 +-1 +187 +-1 +69 +161 +82 +-1 +458 +-1 +-1 +174 +231 +-1 +-1 +-1 +427 +-1 +-1 +182 +234 +-1 +83 +218 +-1 +271 +-1 +33 +-1 +-1 +42 +-1 +-1 +429 +406 +-1 +481 +279 +77 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +95 +112 +117 +-1 +488 +-1 +336 +-1 +-1 +152 +40 +-1 +-1 +41 +113 +-1 +-1 +318 +215 +-1 +-1 +75 +152 +15 +158 +163 +205 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_3.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_3.txt new file mode 100644 index 0000000..10136b0 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_3.txt @@ -0,0 +1,100 @@ +27 +25 +126 +83 +204 +127 +17 +239 +98 +103 +175 +446 +564 +39 +309 +238 +354 +126 +94 +83 +54 +165 +392 +156 +147 +241 +120 +111 +415 +71 +145 +203 +-1 +52 +195 +-1 +54 +148 +-1 +-1 +155 +16 +72 +383 +266 +216 +26 +422 +245 +61 +296 +45 +151 +164 +-1 +119 +254 +37 +141 +-1 +-1 +346 +154 +22 +69 +18 +96 +312 +105 +117 +-1 +120 +50 +51 +151 +240 +548 +-1 +161 +111 +-1 +-1 +130 +75 +95 +151 +-1 +225 +-1 +-1 +181 +38 +210 +566 +132 +110 +-1 +203 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_4.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_4.txt new file mode 100644 index 0000000..7faf3a1 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_4.txt @@ -0,0 +1,100 @@ +106 +131 +129 +146 +151 +49 +70 +264 +80 +37 +131 +88 +105 +211 +119 +71 +64 +76 +53 +134 +41 +50 +213 +259 +211 +533 +57 +235 +65 +210 +110 +227 +101 +187 +343 +140 +38 +168 +158 +48 +37 +77 +42 +483 +-1 +15 +59 +98 +548 +456 +79 +-1 +235 +-1 +155 +-1 +507 +94 +23 +112 +75 +24 +253 +239 +68 +310 +68 +88 +59 +34 +74 +114 +142 +42 +159 +245 +-1 +120 +62 +138 +16 +-1 +119 +439 +116 +96 +26 +-1 +96 +283 +122 +285 +37 +63 +118 +99 +265 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_5.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_5.txt new file mode 100644 index 0000000..b2def9b --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_5.txt @@ -0,0 +1,100 @@ +46 +58 +47 +135 +135 +201 +245 +405 +130 +200 +157 +-1 +-1 +86 +29 +264 +34 +-1 +44 +-1 +166 +-1 +73 +17 +368 +53 +-1 +37 +335 +18 +76 +195 +-1 +164 +300 +108 +74 +59 +216 +46 +56 +96 +46 +109 +71 +173 +314 +72 +-1 +184 +-1 +123 +410 +243 +-1 +78 +-1 +74 +166 +63 +55 +419 +349 +76 +125 +94 +112 +61 +339 +296 +287 +93 +492 +193 +134 +74 +90 +125 +118 +-1 +134 +62 +171 +101 +193 +446 +252 +517 +-1 +-1 +80 +73 +252 +88 +119 +188 +189 +313 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_6.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_6.txt new file mode 100644 index 0000000..b443d90 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_6.txt @@ -0,0 +1,100 @@ +17 +44 +87 +112 +89 +55 +167 +59 +101 +157 +28 +128 +93 +260 +67 +-1 +57 +53 +154 +-1 +81 +154 +-1 +-1 +212 +-1 +113 +108 +196 +268 +149 +422 +45 +103 +-1 +130 +-1 +312 +234 +81 +-1 +76 +51 +62 +342 +258 +78 +40 +250 +-1 +88 +-1 +124 +109 +188 +80 +244 +423 +364 +179 +57 +-1 +29 +78 +124 +50 +165 +246 +-1 +120 +-1 +108 +44 +193 +-1 +22 +118 +95 +217 +27 +37 +127 +60 +276 +66 +124 +132 +61 +101 +111 +78 +163 +49 +207 +55 +17 +188 +117 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_7.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_7.txt new file mode 100644 index 0000000..e3e739e --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_7.txt @@ -0,0 +1,100 @@ +43 +102 +190 +168 +206 +227 +149 +295 +313 +184 +61 +-1 +372 +26 +178 +-1 +63 +-1 +225 +233 +63 +318 +203 +248 +179 +39 +95 +168 +590 +-1 +571 +562 +163 +218 +46 +323 +123 +563 +82 +20 +229 +208 +31 +442 +-1 +195 +-1 +191 +131 +301 +128 +100 +196 +-1 +42 +191 +71 +189 +50 +75 +28 +107 +340 +64 +27 +63 +50 +73 +183 +97 +57 +-1 +490 +36 +177 +464 +121 +101 +197 +285 +93 +48 +14 +494 +-1 +21 +84 +142 +109 +80 +117 +-1 +133 +112 +19 +110 +-1 +349 +-1 +363 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_8.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_8.txt new file mode 100644 index 0000000..81b6962 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_8.txt @@ -0,0 +1,100 @@ +40 +60 +98 +155 +130 +92 +33 +107 +175 +249 +248 +-1 +-1 +264 +137 +112 +84 +283 +-1 +50 +-1 +55 +240 +188 +-1 +91 +95 +88 +82 +177 +315 +66 +350 +-1 +-1 +-1 +182 +219 +75 +315 +24 +271 +570 +16 +-1 +457 +88 +157 +340 +160 +41 +480 +55 +-1 +195 +274 +135 +49 +523 +25 +469 +531 +497 +-1 +487 +25 +-1 +45 +39 +-1 +422 +169 +141 +269 +148 +159 +228 +85 +212 +213 +41 +126 +69 +205 +136 +34 +147 +315 +141 +-1 +102 +30 +205 +132 +177 +210 +171 +-1 +583 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_9.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_9.txt new file mode 100644 index 0000000..4659bda --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_9.txt @@ -0,0 +1,100 @@ +74 +77 +164 +132 +176 +180 +129 +76 +151 +173 +83 +83 +61 +159 +47 +219 +263 +98 +-1 +110 +-1 +158 +154 +119 +160 +54 +73 +49 +88 +100 +145 +28 +28 +-1 +-1 +132 +390 +172 +228 +37 +462 +17 +396 +15 +154 +151 +409 +176 +66 +212 +-1 +130 +-1 +90 +-1 +144 +411 +101 +-1 +187 +121 +74 +52 +388 +65 +54 +164 +32 +151 +205 +17 +95 +87 +276 +71 +126 +37 +54 +139 +171 +-1 +129 +25 +16 +60 +175 +-1 +97 +-1 +-1 +65 +15 +164 +-1 +-1 +-1 +83 +-1 +445 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_1.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_1.txt new file mode 100644 index 0000000..98e43f5 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_1.txt @@ -0,0 +1,100 @@ +84 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +20 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +25 +-1 +-1 +-1 +74 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +69 +-1 +-1 +87 +-1 +-1 +-1 +-1 +61 +-1 +-1 +-1 +-1 +-1 +-1 +87 +-1 +-1 +-1 +-1 +91 +73 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +69 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +55 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +99 +92 +68 +-1 +-1 +-1 +17 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_10.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_10.txt new file mode 100644 index 0000000..86fd461 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_10.txt @@ -0,0 +1,100 @@ +20 +36 +60 +-1 +-1 +-1 +-1 +-1 +-1 +94 +34 +33 +-1 +23 +75 +57 +-1 +15 +-1 +-1 +44 +-1 +-1 +41 +22 +78 +-1 +58 +70 +-1 +-1 +22 +-1 +-1 +14 +-1 +-1 +-1 +-1 +33 +14 +26 +23 +-1 +-1 +-1 +92 +-1 +-1 +66 +-1 +-1 +-1 +-1 +61 +57 +47 +-1 +52 +-1 +-1 +97 +61 +-1 +-1 +-1 +-1 +90 +-1 +82 +-1 +-1 +-1 +68 +76 +85 +-1 +-1 +-1 +69 +-1 +-1 +-1 +-1 +18 +-1 +46 +-1 +28 +-1 +-1 +-1 +14 +-1 +-1 +76 +59 +-1 +39 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_11.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_11.txt new file mode 100644 index 0000000..d0dbd9a --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_11.txt @@ -0,0 +1,100 @@ +39 +59 +17 +60 +-1 +-1 +-1 +-1 +-1 +69 +33 +26 +-1 +45 +-1 +70 +73 +62 +-1 +99 +-1 +-1 +-1 +53 +-1 +75 +64 +14 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +64 +-1 +-1 +-1 +21 +-1 +-1 +30 +96 +-1 +-1 +-1 +14 +14 +49 +88 +-1 +-1 +-1 +-1 +40 +-1 +-1 +-1 +-1 +39 +28 +-1 +-1 +-1 +40 +-1 +82 +-1 +-1 +-1 +-1 +-1 +-1 +77 +-1 +-1 +44 +-1 +-1 +62 +-1 +20 +92 +37 +-1 +-1 +-1 +63 +-1 +14 +-1 +38 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_12.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_12.txt new file mode 100644 index 0000000..008c989 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_12.txt @@ -0,0 +1,100 @@ +67 +70 +-1 +-1 +92 +-1 +-1 +-1 +53 +-1 +24 +63 +-1 +-1 +-1 +-1 +41 +-1 +78 +22 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +20 +22 +48 +-1 +-1 +-1 +92 +-1 +80 +53 +71 +18 +59 +-1 +-1 +84 +39 +-1 +32 +-1 +27 +91 +59 +30 +62 +-1 +80 +-1 +72 +-1 +-1 +73 +-1 +15 +30 +30 +-1 +-1 +-1 +-1 +44 +37 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +22 +51 +86 +40 +87 +-1 +-1 +-1 +-1 +-1 +-1 +31 +18 +-1 +59 +42 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_13.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_13.txt new file mode 100644 index 0000000..1e39d98 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_13.txt @@ -0,0 +1,100 @@ +21 +33 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +37 +47 +-1 +51 +97 +-1 +-1 +64 +-1 +19 +98 +-1 +-1 +44 +-1 +-1 +-1 +-1 +86 +-1 +-1 +-1 +-1 +68 +69 +62 +-1 +-1 +36 +-1 +-1 +-1 +-1 +21 +-1 +-1 +-1 +-1 +-1 +48 +15 +-1 +-1 +91 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +30 +-1 +-1 +-1 +-1 +-1 +53 +14 +-1 +-1 +-1 +-1 +57 +-1 +-1 +39 +-1 +36 +72 +-1 +47 +-1 +-1 +-1 +-1 +-1 +41 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_14.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_14.txt new file mode 100644 index 0000000..a0b1090 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_14.txt @@ -0,0 +1,100 @@ +38 +73 +67 +-1 +-1 +-1 +-1 +-1 +59 +-1 +88 +54 +-1 +-1 +70 +52 +-1 +-1 +-1 +-1 +43 +-1 +-1 +-1 +-1 +-1 +92 +-1 +-1 +-1 +64 +91 +-1 +-1 +-1 +-1 +68 +-1 +79 +54 +-1 +51 +-1 +63 +43 +-1 +93 +-1 +-1 +-1 +-1 +28 +-1 +44 +38 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +84 +-1 +38 +57 +-1 +-1 +-1 +45 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +65 +35 +-1 +76 +-1 +44 +-1 +-1 +33 +39 +-1 +54 +-1 +-1 +-1 +-1 +-1 +-1 +88 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_15.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_15.txt new file mode 100644 index 0000000..f7c1a2d --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_15.txt @@ -0,0 +1,100 @@ +14 +50 +69 +58 +-1 +34 +-1 +-1 +71 +-1 +-1 +26 +52 +42 +17 +-1 +-1 +41 +93 +-1 +-1 +-1 +34 +18 +93 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +53 +-1 +-1 +29 +82 +15 +50 +39 +-1 +72 +36 +83 +98 +-1 +-1 +-1 +-1 +20 +31 +-1 +-1 +-1 +-1 +-1 +32 +62 +-1 +81 +-1 +-1 +28 +-1 +47 +-1 +-1 +-1 +-1 +-1 +-1 +14 +100 +68 +-1 +61 +-1 +-1 +-1 +37 +26 +-1 +96 +-1 +-1 +24 +-1 +-1 +-1 +-1 +-1 +75 +-1 +-1 +47 +90 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_16.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_16.txt new file mode 100644 index 0000000..edb79c4 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_16.txt @@ -0,0 +1,100 @@ +14 +45 +32 +81 +-1 +95 +-1 +-1 +-1 +-1 +86 +-1 +-1 +-1 +29 +-1 +93 +-1 +-1 +66 +-1 +44 +-1 +66 +-1 +44 +49 +-1 +-1 +14 +18 +43 +-1 +98 +-1 +-1 +-1 +20 +-1 +67 +-1 +53 +-1 +-1 +-1 +-1 +-1 +-1 +14 +28 +-1 +39 +58 +-1 +26 +-1 +-1 +63 +64 +68 +34 +-1 +99 +63 +-1 +-1 +32 +91 +-1 +32 +63 +-1 +38 +-1 +-1 +38 +-1 +41 +39 +-1 +-1 +-1 +65 +33 +-1 +60 +-1 +-1 +67 +43 +-1 +-1 +74 +94 +-1 +-1 +67 +-1 +-1 +87 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_2.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_2.txt new file mode 100644 index 0000000..2f13c2a --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_2.txt @@ -0,0 +1,100 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +38 +-1 +43 +-1 +-1 +-1 +-1 +-1 +-1 +33 +-1 +70 +67 +33 +-1 +-1 +-1 +-1 +17 +-1 +-1 +-1 +-1 +-1 +26 +55 +-1 +-1 +-1 +100 +-1 +69 +-1 +-1 +-1 +-1 +15 +-1 +33 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +68 +-1 +-1 +-1 +82 +56 +-1 +17 +56 +-1 +-1 +-1 +92 +-1 +22 +-1 +-1 +-1 +51 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_3.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_3.txt new file mode 100644 index 0000000..5a1d718 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_3.txt @@ -0,0 +1,100 @@ +71 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +33 +62 +-1 +-1 +-1 +-1 +-1 +-1 +74 +-1 +-1 +-1 +-1 +-1 +86 +-1 +-1 +22 +-1 +38 +-1 +40 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +23 +-1 +-1 +-1 +-1 +73 +17 +-1 +-1 +-1 +65 +92 +-1 +85 +34 +-1 +98 +-1 +-1 +-1 +-1 +58 +-1 +59 +-1 +66 +-1 +-1 +-1 +-1 +30 +-1 +-1 +24 +-1 +-1 +-1 +41 +-1 +76 +86 +-1 +-1 +54 +-1 +53 +56 +59 +-1 +14 +43 +22 +-1 +-1 +-1 +55 +94 +-1 +-1 +-1 +-1 +96 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_4.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_4.txt new file mode 100644 index 0000000..34118de --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_4.txt @@ -0,0 +1,100 @@ +47 +58 +87 +-1 +-1 +-1 +-1 +-1 +17 +37 +88 +45 +78 +-1 +75 +-1 +32 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +98 +55 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +84 +43 +-1 +-1 +-1 +50 +76 +-1 +-1 +-1 +-1 +81 +69 +76 +-1 +-1 +43 +77 +-1 +-1 +-1 +-1 +-1 +92 +-1 +-1 +60 +-1 +-1 +46 +45 +-1 +-1 +-1 +90 +53 +24 +33 +37 +-1 +80 +-1 +-1 +49 +-1 +-1 +53 +-1 +-1 +63 +-1 +83 +-1 +-1 +-1 +57 +-1 +-1 +-1 +-1 +47 +-1 +64 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_5.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_5.txt new file mode 100644 index 0000000..8127599 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_5.txt @@ -0,0 +1,100 @@ +37 +54 +73 +17 +-1 +-1 +-1 +-1 +-1 +82 +76 +15 +-1 +81 +-1 +73 +-1 +39 +57 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +60 +-1 +-1 +-1 +-1 +93 +-1 +36 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +72 +-1 +-1 +-1 +48 +16 +-1 +-1 +-1 +-1 +62 +-1 +-1 +-1 +-1 +88 +87 +63 +80 +-1 +-1 +-1 +37 +27 +-1 +-1 +-1 +25 +-1 +95 +29 +72 +46 +-1 +42 +74 +-1 +14 +-1 +-1 +40 +-1 +57 +-1 +-1 +95 +-1 +-1 +52 +-1 +37 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_5_old.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_5_old.txt new file mode 100644 index 0000000..1796809 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_5_old.txt @@ -0,0 +1,100 @@ +37 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +48 +30 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +27 +-1 +64 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +44 +-1 +-1 +50 +16 +-1 +-1 +98 +-1 +-1 +-1 +-1 +-1 +-1 +99 +-1 +-1 +-1 +-1 +53 +-1 +88 +-1 +-1 +39 +-1 +-1 +78 +-1 +-1 +37 +69 +14 +-1 +72 +-1 +-1 +-1 +48 +-1 +30 +48 +32 +-1 +-1 +98 +-1 +27 +57 +-1 +97 +-1 +-1 +35 +-1 +-1 +-1 +81 +-1 +-1 +-1 +67 +-1 +-1 +-1 +67 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_6.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_6.txt new file mode 100644 index 0000000..785e04a --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_6.txt @@ -0,0 +1,100 @@ +16 +37 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +25 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +71 +-1 +-1 +-1 +-1 +79 +-1 +92 +-1 +42 +-1 +-1 +-1 +-1 +54 +-1 +-1 +-1 +21 +-1 +16 +23 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +49 +-1 +43 +28 +-1 +43 +-1 +99 +-1 +38 +-1 +-1 +-1 +50 +40 +-1 +68 +-1 +-1 +15 +-1 +-1 +-1 +-1 +-1 +39 +-1 +-1 +40 +78 +86 +100 +-1 +-1 +-1 +99 +-1 +33 +-1 +-1 +46 +-1 +-1 +-1 +49 +-1 +80 +-1 +73 +77 +88 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_7.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_7.txt new file mode 100644 index 0000000..1b0e0df --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_7.txt @@ -0,0 +1,100 @@ +18 +50 +81 +-1 +-1 +-1 +-1 +-1 +-1 +40 +-1 +74 +77 +-1 +-1 +-1 +44 +-1 +-1 +-1 +98 +41 +-1 +59 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +18 +100 +-1 +-1 +-1 +-1 +57 +31 +-1 +-1 +-1 +38 +-1 +-1 +-1 +29 +-1 +32 +-1 +63 +-1 +-1 +-1 +58 +-1 +-1 +48 +-1 +-1 +65 +49 +39 +-1 +-1 +-1 +-1 +35 +-1 +-1 +33 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +65 +74 +-1 +-1 +-1 +34 +32 +-1 +-1 +39 +-1 +41 +-1 +-1 +-1 +-1 +33 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_8.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_8.txt new file mode 100644 index 0000000..0c57aa4 --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_8.txt @@ -0,0 +1,100 @@ +50 +81 +96 +-1 +-1 +-1 +-1 +14 +75 +-1 +58 +51 +-1 +-1 +68 +-1 +-1 +-1 +42 +-1 +46 +52 +63 +-1 +-1 +88 +-1 +-1 +-1 +20 +-1 +59 +-1 +-1 +-1 +-1 +15 +-1 +-1 +-1 +61 +-1 +-1 +-1 +-1 +73 +91 +-1 +67 +-1 +-1 +47 +-1 +40 +-1 +51 +81 +61 +15 +-1 +-1 +-1 +-1 +-1 +89 +74 +-1 +-1 +18 +53 +41 +-1 +51 +36 +34 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +89 +28 +46 +-1 +54 +22 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_9.txt b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_9.txt new file mode 100644 index 0000000..143612e --- /dev/null +++ b/python/plots/how_many_generations/data/population_size_100_runs/how_many_generations_5x5_k8_population_size_9.txt @@ -0,0 +1,100 @@ +38 +47 +62 +29 +32 +19 +-1 +-1 +-1 +-1 +-1 +-1 +58 +-1 +-1 +-1 +80 +-1 +-1 +49 +-1 +-1 +-1 +-1 +-1 +15 +81 +16 +-1 +44 +95 +66 +64 +-1 +-1 +72 +-1 +-1 +-1 +35 +-1 +85 +42 +-1 +-1 +-1 +-1 +-1 +78 +-1 +63 +-1 +-1 +57 +23 +-1 +-1 +-1 +-1 +-1 +-1 +98 +51 +-1 +32 +61 +-1 +62 +-1 +53 +-1 +25 +-1 +54 +44 +-1 +73 +49 +-1 +-1 +-1 +-1 +-1 +61 +48 +-1 +-1 +-1 +-1 +-1 +51 +71 +50 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data/times.txt b/python/plots/how_many_generations/data/times.txt new file mode 100644 index 0000000..26e7d70 --- /dev/null +++ b/python/plots/how_many_generations/data/times.txt @@ -0,0 +1,173 @@ +Execution times on i7-6700 CPU @3.40GHz, 4 cores @ 100% workload using +Python's multiprocessing module + + +####################### 2x2 Chimera grid different K graphs #################### + +◾ Params +population_size = 12 +max_mutation_trials = 30 +mutation_extend_to_free_neighbors_probability = 0.3 +max_total = 1000 +max_generations = 100 +remove_redundancy_probability = 0.01 +m = 2 # grid size +n = 2 # grid size +t = 4 # shore size + +⏱ how_many_generations_2x2 (1000 a time) +- K2: 2.96s +- K3: 10.90s +- K4: 25.61s +- K5: 52.77s +- K6: 131.34s +- K7: 276.01s +- K8: 632.42s +- K9: 839.06s +- K10: ? (around the same time as K9) + + +######################## K8 different Chimera grid sizes ####################### + +◾ Params +population_size = 12 +max_mutation_trials = 30 +mutation_extend_to_free_neighbors_probability = 0.3 +max_total = 100 +max_generations = 100 +remove_redundancy_probability = 0.01 +t = 4 # shore size + +⏱ how_many_generations_mxm (100 a time) +- 2x2: 61.78s +- 3x3: 119.37s +- 4x4: 201.84s +- 5x5: 299.73s +- 6x6: 430.39s +- 7x7: 502.94s +- 8x8: 638.90s +- 9x9: 803.30s + + +####################### K8 different population sizes (100) #################### + +◾ Params +max_mutation_trials = 30 +mutation_extend_to_free_neighbors_probability = 0.3 +max_total = 100 +max_generations = 100 +remove_redundancy_probability = 0.01 +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + +⏱ how_many_generations_population_size (100 a time) +- 1: 38.82s +- 2: 61.40s +- 3: 90.75s +- 4: 109.35s +- 5: 140.66s +- 6: 168.38s +- 7: 192.45s +- 8: 205.01s +- 9: 233.09s +- 10: 236.01s +- 11: 251.86s +- 12: 288.17s +- 13: 339.22s +- 14: 378.01s +- 15: 343.30s +- 16: 371.73s + + +###################### K8 different population sizes (100) ##################### + +◾ Params +max_mutation_trials = 30 +mutation_extend_to_free_neighbors_probability = 0.3 +max_total = 100 +max_generations = 600 +remove_redundancy_probability = 0.01 +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + +⏱ how_many_generations_population_size (100 a time) +- 1: 128.87s +- 2: 224.79s +- 3: 281.21s +- 4: 259.75s +- 5: 385.54s +- 6: 408.23s +- 7: 505.68s +- 8: 648.50s +- 9: 652.14s +- 10: 718.90s +- 11: 618.84s +- 12: 862.02s +- 13: 843.26s +- 14: 914.88s +- 15: 435.01s +- 16: 382.50s +- 17: 607.80s (started to run another task with 100%) +- 18: 735.05s +- 19: +- 20: + + +####################### K8 different population sizes (1000) ################### + +Marc💥 +◾ Params +max_mutation_trials = 30 +mutation_extend_to_free_neighbors_probability = 0.3 +max_total = 1000 +max_generations = 100 +remove_redundancy_probability = 0.01 +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + +⏱ how_many_generations_population_size (1000 a time) + + +###################### K8 different population sizes (1000) #################### + +Marc💥 +◾ Params +max_mutation_trials = 30 +mutation_extend_to_free_neighbors_probability = 0.3 +max_total = 1000 +max_generations = 600 +remove_redundancy_probability = 0.01 +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + +⏱ how_many_generations_population_size (1000 a time) + + +######################## K8 different probabilities (50) ####################### + +◾ Params +population_size=4, +max_mutation_trials=30 +max_total = 50 +max_generations = 600 +remove_redundancy_probability = 0.01 +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + +⏱ how_many_generations_extend_to_free_probability (50 a time) +- 0.00: 132.61s +- 0.11: 276.20s +- 0.22: 359.29s +- 0.33: 272.75s +- 0.44: 269.85s +- 0.55: 301.38s +- 0.66: 326.49s +- 0.77: 332.97s +- 0.88: 357.85s +- 1.00: 226.74s + \ No newline at end of file diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/docker-compose.yml b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/docker-compose.yml new file mode 100644 index 0000000..517b2af --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/docker-compose.yml @@ -0,0 +1,21 @@ +services: + major-miner: + build: . + container_name: major-miner + environment: + CORE_PERCENTAGE: 90 + MAX_MUTATION_TRIALS: 30 + PROB_EXTEND_TO_FREE_NEIGHBOR: 0.3 + MAX_TOTAL: 1000 + MAX_GENERATIONS: 600 + PROB_REMOVE_REDUNDANCY: 0.01 + GRID_M: 5 + GRID_N: 5 + K_GRAPH: 8 + POPSIZE_MIN: 1 + POPSIZE_MAX: 20 + + volumes: + - type: bind + source: ./out + target: /app/out diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/evolution.py b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/evolution.py new file mode 100644 index 0000000..7452778 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/evolution.py @@ -0,0 +1,143 @@ +# Move this file to src/solver to start +# Disable logger! + +import logging +import multiprocessing +import os +import shutil +import time +from functools import partial +from random import random +from typing import Optional + +from src.drawing.draw import DrawEmbedding +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + +################################# Params ####################################### + +max_total = 10 +max_generations = 600 +remove_redundancy_probability = 0.01 + +# Chimera graph +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + + +############################### Evolution ###################################### +d = DrawEmbedding(m, n, t) + + +def different_params(): + # --- Clear + try: + shutil.rmtree('./out/') + except FileNotFoundError: + pass + os.mkdir('./out') + + for population_size in range(1, 21): + print(f'Started population size {population_size}') + graph_number = 8 + graph = TestGraph.k(graph_number) + start_time = time.time() + start_multiprocessing((graph, population_size), f'k{graph_number}popsize{population_size}') + duration = time.time() - start_time + print(f'Duration for population size {population_size}: {duration} s') + + +def start_multiprocessing(plot_params, name: str): + processes = multiprocessing.cpu_count() * int(os.getenv('CORE_PERCENTAGE', 90)) // 100 + with multiprocessing.Pool(processes) as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, plot_params), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/howManyGenerations_{m}x{n}_{max_total}_{max_generations}gen_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(plot_params, j) -> int: + solver = EmbeddingSolver(plot_params[0], m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver, plot_params) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + save_embedding(*solver.get_embedding(), d, f'{j}-{i}final', plot_params, + title=f'Generation {i} (final with redundancy removed)') + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver, plot_params) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + evo_params = EvolutionParams( + population_size=plot_params[1], + max_mutation_trials=30, + mutation_extend_to_free_neighbors_probability=0.3 + ) + + child = solver.generate_population_and_select(evo_params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + +def save_embedding(nodes: set[int], edges: set[tuple[int, int, int]], + mapping_G_to_H, d: DrawEmbedding, name: str, plot_params, title=''): + logger.info('') + logger.info('🎈 Current embedding') + logger.info(f'edges: {edges}') + logger.info(f'mapping_G_to_H: {mapping_G_to_H}') + + d.draw_whole_embedding_step(nodes, edges, mapping_G_to_H, title=title) + + folder_path = f'./out/popsize{plot_params[1]}' + if not os.path.exists(folder_path): + os.mkdir(folder_path) + d.save_and_clear(os.path.join(folder_path, f'{name}.svg')) + + +if __name__ == "__main__": + different_params() diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/evolution_dockerized.py b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/evolution_dockerized.py new file mode 100644 index 0000000..a817c51 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/evolution_dockerized.py @@ -0,0 +1,144 @@ +# Move this file to src/solver to start +# Disable logger! + +import logging +import multiprocessing +import os +import shutil +import time +from functools import partial +from random import random +from typing import Optional + +from src.drawing.draw import DrawEmbedding +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + +################################# Params ####################################### + +max_total = int(os.getenv('MAX_TOTAL', 300)) +max_generations = int(os.getenv('MAX_GENERATIONS', 600)) +remove_redundancy_probability = float(os.getenv('PROB_REMOVE_REDUNDANCY', 0.01)) + +# Chimera graph +m = int(os.getenv('GRID_M', 5)) # grid size +n = int(os.getenv('GRID_N', 5)) # grid size +t = 4 # shore size + + +############################### Evolution ###################################### +d = DrawEmbedding(m, n, t) + + +def different_params(): + # --- Clear + try: + shutil.rmtree('./out/') + except FileNotFoundError: + pass + os.mkdir('./out') + + for population_size in range(int(os.getenv('POPSIZE_MIN', 1)), int(os.getenv('POPSIZE_MAX', 20)) + 1): + print(f'Started population size {population_size}') + graph_number = int(os.getenv('K_GRAPH', 8)) + graph = TestGraph.k(graph_number) + start_time = time.time() + start_multiprocessing((graph, population_size), f'k{graph_number}popsize{population_size}') + duration = time.time() - start_time + print(f'Duration for population size {population_size}: {duration} s') + + +def start_multiprocessing(plot_params, name: str): + processes = multiprocessing.cpu_count() * int(os.getenv('CORE_PERCENTAGE', 75)) // 100 + with multiprocessing.Pool(processes) as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, plot_params), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/howManyGenerations_{m}x{n}_{max_total}_{max_generations}gen_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(plot_params, j) -> int: + solver = EmbeddingSolver(plot_params[0], m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver, plot_params) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + save_embedding(*solver.get_embedding(), d, f'{j}-{i}final', plot_params, + title=f'Generation {i} (final with redundancy removed)') + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver, plot_params) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + evo_params = EvolutionParams( + population_size=plot_params[1], + max_mutation_trials=int(os.getenv('MAX_MUTATION_TRIALS', 30)), + mutation_extend_to_free_neighbors_probability=float( + os.getenv('PROB_EXTEND_TO_FREE_NEIGHBOR', 0.3)) + ) + + child = solver.generate_population_and_select(evo_params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + +def save_embedding(nodes: set[int], edges: set[tuple[int, int, int]], + mapping_G_to_H, d: DrawEmbedding, name: str, plot_params, title=''): + logger.info('') + logger.info('🎈 Current embedding') + logger.info(f'edges: {edges}') + logger.info(f'mapping_G_to_H: {mapping_G_to_H}') + + d.draw_whole_embedding_step(nodes, edges, mapping_G_to_H, title=title) + + folder_path = f'./out/popsize{plot_params[1]}' + if not os.path.exists(folder_path): + os.mkdir(folder_path) + d.save_and_clear(os.path.join(folder_path, f'{name}.svg')) + + +if __name__ == "__main__": + different_params() diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize1.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize1.txt new file mode 100644 index 0000000..1c5fe31 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize1.txt @@ -0,0 +1,10 @@ +241 +-1 +346 +-1 +477 +-1 +88 +242 +310 +450 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize10.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize10.txt new file mode 100644 index 0000000..a44056c --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize10.txt @@ -0,0 +1,10 @@ +43 +59 +41 +20 +116 +24 +185 +346 +475 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize11.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize11.txt new file mode 100644 index 0000000..942cd39 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize11.txt @@ -0,0 +1,10 @@ +32 +33 +30 +60 +58 +84 +96 +222 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize12.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize12.txt new file mode 100644 index 0000000..684c8ce --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize12.txt @@ -0,0 +1,10 @@ +17 +41 +50 +27 +200 +163 +191 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize13.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize13.txt new file mode 100644 index 0000000..8bd8391 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize13.txt @@ -0,0 +1,10 @@ +49 +80 +14 +111 +124 +144 +58 +76 +85 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize14.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize14.txt new file mode 100644 index 0000000..7b92053 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize14.txt @@ -0,0 +1,10 @@ +40 +15 +52 +168 +280 +228 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize15.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize15.txt new file mode 100644 index 0000000..1ab07b7 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize15.txt @@ -0,0 +1,10 @@ +23 +62 +70 +85 +30 +43 +191 +175 +106 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize16.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize16.txt new file mode 100644 index 0000000..1c250d4 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize16.txt @@ -0,0 +1,10 @@ +22 +50 +97 +99 +128 +120 +115 +105 +203 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize17.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize17.txt new file mode 100644 index 0000000..b1c0096 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize17.txt @@ -0,0 +1,10 @@ +85 +18 +131 +172 +22 +58 +321 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize18.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize18.txt new file mode 100644 index 0000000..b7205cb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize18.txt @@ -0,0 +1,10 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize19.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize19.txt new file mode 100644 index 0000000..b7205cb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize19.txt @@ -0,0 +1,10 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize2.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize2.txt new file mode 100644 index 0000000..7f24cb8 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize2.txt @@ -0,0 +1,10 @@ +28 +79 +164 +-1 +561 +-1 +51 +-1 +99 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize20.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize20.txt new file mode 100644 index 0000000..b7205cb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize20.txt @@ -0,0 +1,10 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize3.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize3.txt new file mode 100644 index 0000000..9783af3 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize3.txt @@ -0,0 +1,10 @@ +78 +74 +161 +123 +215 +242 +159 +145 +312 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize4.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize4.txt new file mode 100644 index 0000000..8d92ce0 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize4.txt @@ -0,0 +1,10 @@ +14 +73 +100 +173 +88 +35 +220 +187 +182 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize5.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize5.txt new file mode 100644 index 0000000..1640eec --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize5.txt @@ -0,0 +1,10 @@ +16 +25 +115 +126 +215 +26 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize6.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize6.txt new file mode 100644 index 0000000..21e06e5 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize6.txt @@ -0,0 +1,10 @@ +64 +75 +62 +78 +16 +48 +247 +140 +238 +442 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize7.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize7.txt new file mode 100644 index 0000000..46f53ab --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize7.txt @@ -0,0 +1,10 @@ +26 +29 +71 +57 +14 +75 +50 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize8.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize8.txt new file mode 100644 index 0000000..cd62020 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize8.txt @@ -0,0 +1,10 @@ +14 +43 +69 +112 +185 +19 +33 +218 +282 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize9.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize9.txt new file mode 100644 index 0000000..1661b32 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize9.txt @@ -0,0 +1,10 @@ +104 +158 +178 +80 +277 +25 +289 +108 +498 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize1.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize1.txt new file mode 100644 index 0000000..c0e44ea --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize1.txt @@ -0,0 +1,300 @@ +316 +136 +21 +-1 +123 +-1 +123 +286 +516 +-1 +-1 +241 +110 +133 +242 +189 +495 +-1 +76 +80 +-1 +149 +44 +-1 +-1 +140 +-1 +126 +-1 +302 +271 +171 +-1 +-1 +39 +-1 +36 +138 +357 +142 +-1 +149 +350 +260 +322 +125 +66 +60 +-1 +29 +192 +-1 +140 +105 +134 +40 +57 +121 +233 +-1 +-1 +204 +-1 +-1 +222 +62 +108 +24 +42 +-1 +123 +143 +388 +354 +257 +192 +95 +-1 +241 +186 +482 +59 +62 +56 +52 +249 +-1 +123 +-1 +-1 +-1 +94 +102 +310 +94 +187 +174 +169 +230 +174 +530 +-1 +409 +242 +-1 +175 +-1 +283 +-1 +61 +-1 +177 +374 +437 +91 +207 +20 +219 +139 +53 +55 +148 +-1 +35 +199 +-1 +345 +-1 +128 +212 +384 +-1 +154 +20 +50 +155 +-1 +548 +197 +-1 +-1 +134 +25 +513 +105 +143 +237 +231 +-1 +234 +264 +113 +-1 +271 +-1 +320 +-1 +-1 +352 +319 +174 +-1 +-1 +142 +398 +-1 +332 +57 +425 +-1 +-1 +403 +406 +85 +145 +-1 +-1 +464 +129 +-1 +154 +197 +-1 +197 +295 +232 +-1 +-1 +141 +-1 +178 +380 +102 +38 +315 +161 +-1 +218 +127 +376 +211 +252 +140 +298 +-1 +146 +52 +100 +112 +333 +-1 +321 +402 +-1 +61 +22 +58 +193 +191 +-1 +18 +283 +-1 +169 +252 +230 +-1 +234 +31 +182 +88 +257 +166 +116 +367 +134 +104 +103 +-1 +-1 +363 +-1 +179 +33 +111 +-1 +199 +444 +186 +-1 +537 +427 +593 +218 +102 +197 +-1 +360 +83 +28 +39 +366 +21 +190 +402 +134 +56 +166 +-1 +317 +235 +175 +54 +273 +60 +186 +313 +175 +201 +234 +89 +199 +140 +457 +-1 +170 +178 +229 +351 +26 +169 +103 +-1 +263 +169 +119 +564 +461 +262 +156 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize10.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize10.txt new file mode 100644 index 0000000..1b15f4e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize10.txt @@ -0,0 +1,300 @@ +29 +134 +63 +138 +26 +-1 +44 +-1 +214 +-1 +206 +83 +-1 +81 +33 +113 +42 +53 +17 +534 +72 +66 +113 +295 +209 +51 +21 +-1 +365 +59 +526 +222 +428 +223 +31 +260 +-1 +-1 +64 +324 +33 +182 +75 +46 +201 +31 +175 +74 +56 +18 +174 +66 +-1 +214 +25 +-1 +18 +113 +-1 +26 +38 +30 +58 +294 +-1 +48 +105 +137 +96 +34 +14 +90 +131 +364 +121 +-1 +198 +337 +37 +23 +16 +82 +113 +35 +-1 +128 +236 +235 +101 +276 +128 +47 +246 +63 +59 +82 +-1 +70 +147 +70 +32 +-1 +-1 +18 +61 +35 +57 +78 +33 +467 +125 +59 +-1 +119 +64 +185 +-1 +60 +35 +54 +147 +-1 +188 +349 +158 +146 +171 +28 +237 +27 +-1 +250 +529 +180 +47 +99 +387 +53 +19 +-1 +28 +298 +206 +41 +63 +19 +82 +202 +571 +60 +28 +47 +143 +230 +40 +-1 +149 +188 +179 +-1 +148 +70 +46 +179 +33 +30 +182 +17 +66 +29 +39 +193 +15 +73 +33 +96 +58 +148 +56 +105 +67 +61 +101 +-1 +49 +24 +152 +36 +21 +-1 +17 +14 +-1 +20 +27 +43 +119 +332 +73 +106 +27 +252 +143 +415 +28 +44 +147 +469 +303 +166 +189 +71 +-1 +105 +-1 +190 +88 +41 +-1 +27 +185 +116 +16 +103 +190 +26 +223 +412 +373 +26 +-1 +365 +139 +80 +300 +256 +-1 +45 +280 +51 +91 +15 +46 +91 +256 +-1 +53 +168 +188 +209 +-1 +38 +-1 +188 +237 +66 +-1 +46 +30 +-1 +184 +23 +82 +37 +25 +123 +84 +257 +195 +93 +-1 +14 +75 +522 +15 +-1 +83 +254 +213 +98 +115 +262 +200 +118 +100 +473 +60 +-1 +206 +15 +137 +-1 +268 +36 +68 +130 +-1 +-1 +75 +337 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize11.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize11.txt new file mode 100644 index 0000000..aa9075d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize11.txt @@ -0,0 +1,300 @@ +51 +155 +52 +102 +34 +74 +-1 +177 +52 +112 +-1 +119 +50 +115 +220 +136 +-1 +-1 +58 +18 +-1 +22 +96 +42 +22 +45 +144 +241 +75 +-1 +149 +14 +-1 +15 +452 +-1 +213 +93 +51 +-1 +-1 +41 +-1 +57 +-1 +-1 +85 +23 +439 +106 +45 +-1 +19 +33 +21 +29 +53 +15 +18 +36 +135 +-1 +43 +77 +16 +-1 +498 +20 +-1 +66 +105 +36 +109 +17 +190 +102 +231 +16 +132 +-1 +101 +515 +-1 +168 +230 +53 +128 +36 +95 +102 +61 +69 +42 +65 +72 +382 +42 +99 +34 +24 +80 +43 +-1 +419 +105 +219 +125 +-1 +108 +31 +37 +-1 +240 +77 +315 +23 +74 +-1 +58 +-1 +47 +204 +34 +63 +83 +249 +17 +67 +163 +22 +42 +47 +-1 +28 +142 +-1 +64 +207 +-1 +75 +81 +48 +148 +30 +44 +-1 +99 +19 +-1 +140 +50 +76 +185 +30 +-1 +99 +23 +67 +188 +96 +431 +116 +50 +48 +183 +-1 +303 +565 +60 +76 +27 +-1 +-1 +16 +36 +224 +78 +44 +50 +-1 +-1 +21 +144 +198 +189 +31 +281 +-1 +28 +-1 +172 +38 +40 +-1 +103 +49 +290 +242 +130 +-1 +-1 +72 +-1 +61 +36 +38 +250 +75 +-1 +-1 +-1 +33 +32 +46 +-1 +47 +26 +250 +82 +66 +74 +14 +47 +60 +133 +17 +98 +52 +-1 +-1 +135 +16 +25 +18 +-1 +14 +66 +-1 +20 +15 +159 +363 +246 +334 +190 +39 +31 +73 +-1 +33 +50 +330 +229 +-1 +15 +52 +-1 +91 +62 +547 +54 +102 +33 +58 +78 +23 +238 +183 +104 +-1 +-1 +24 +-1 +33 +116 +392 +-1 +156 +14 +178 +160 +-1 +161 +106 +326 +17 +65 +34 +254 +38 +-1 +54 +22 +216 +37 +168 +99 +47 +229 +342 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize12.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize12.txt new file mode 100644 index 0000000..6ef0fef --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize12.txt @@ -0,0 +1,300 @@ +377 +247 +-1 +-1 +45 +324 +348 +416 +51 +29 +63 +34 +147 +154 +30 +261 +-1 +51 +56 +198 +101 +35 +266 +107 +218 +-1 +85 +-1 +82 +231 +23 +245 +73 +65 +65 +455 +74 +14 +-1 +25 +124 +24 +-1 +200 +-1 +-1 +111 +186 +42 +180 +65 +-1 +73 +269 +62 +292 +114 +49 +88 +232 +27 +114 +-1 +125 +-1 +357 +60 +65 +164 +76 +-1 +21 +16 +367 +105 +20 +254 +70 +-1 +118 +-1 +43 +35 +-1 +14 +17 +116 +80 +40 +17 +28 +119 +23 +76 +-1 +102 +401 +89 +186 +30 +147 +52 +26 +81 +17 +16 +61 +120 +157 +358 +152 +311 +245 +-1 +87 +24 +-1 +43 +60 +67 +122 +88 +169 +35 +-1 +67 +16 +140 +75 +31 +-1 +186 +-1 +133 +59 +28 +36 +38 +88 +63 +28 +-1 +-1 +-1 +169 +23 +68 +56 +104 +-1 +18 +46 +48 +-1 +125 +24 +124 +182 +52 +276 +-1 +-1 +-1 +-1 +392 +93 +18 +88 +15 +51 +410 +210 +43 +102 +116 +54 +413 +50 +86 +-1 +56 +213 +59 +199 +42 +129 +-1 +-1 +67 +67 +35 +14 +31 +95 +45 +108 +79 +41 +93 +61 +44 +35 +-1 +75 +-1 +18 +81 +97 +22 +-1 +73 +147 +167 +69 +486 +-1 +175 +557 +32 +16 +26 +206 +66 +14 +73 +156 +-1 +26 +146 +21 +19 +74 +-1 +64 +273 +144 +-1 +49 +298 +46 +258 +37 +496 +75 +139 +519 +150 +82 +70 +87 +131 +241 +93 +-1 +182 +308 +52 +19 +59 +16 +76 +97 +116 +-1 +36 +-1 +111 +162 +-1 +140 +413 +370 +322 +64 +-1 +25 +47 +-1 +133 +-1 +205 +95 +94 +102 +14 +74 +47 +33 +-1 +26 +39 +48 +61 +134 +25 +-1 +232 +-1 +377 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize2.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize2.txt new file mode 100644 index 0000000..5aaceec --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize2.txt @@ -0,0 +1,300 @@ +88 +74 +-1 +-1 +173 +-1 +204 +100 +28 +-1 +236 +69 +-1 +199 +70 +142 +197 +28 +268 +170 +-1 +197 +50 +96 +169 +-1 +-1 +121 +58 +216 +92 +258 +-1 +93 +-1 +101 +49 +164 +243 +231 +56 +289 +54 +-1 +17 +129 +150 +140 +28 +59 +250 +73 +348 +258 +140 +129 +-1 +96 +29 +-1 +19 +75 +-1 +75 +-1 +171 +234 +83 +237 +85 +81 +-1 +-1 +64 +18 +229 +-1 +356 +344 +83 +142 +141 +58 +111 +64 +277 +190 +45 +54 +42 +110 +131 +310 +220 +217 +176 +37 +245 +44 +48 +-1 +86 +159 +233 +471 +25 +-1 +232 +242 +-1 +144 +49 +230 +-1 +57 +-1 +24 +105 +345 +312 +73 +557 +38 +-1 +131 +324 +44 +-1 +392 +72 +47 +-1 +28 +126 +-1 +122 +239 +-1 +-1 +46 +35 +148 +74 +103 +85 +239 +71 +256 +-1 +-1 +249 +72 +39 +211 +191 +113 +75 +105 +-1 +-1 +131 +410 +-1 +48 +158 +39 +90 +109 +-1 +82 +-1 +93 +236 +115 +249 +188 +211 +68 +-1 +-1 +102 +131 +75 +143 +77 +-1 +-1 +63 +315 +-1 +206 +216 +35 +-1 +49 +33 +257 +312 +69 +342 +265 +153 +244 +-1 +114 +444 +591 +107 +169 +97 +429 +475 +47 +-1 +52 +297 +128 +127 +98 +-1 +145 +178 +15 +284 +167 +-1 +242 +82 +53 +172 +-1 +106 +132 +127 +70 +184 +-1 +241 +27 +83 +-1 +206 +68 +201 +211 +23 +63 +64 +-1 +127 +146 +355 +61 +243 +-1 +198 +74 +24 +-1 +30 +148 +111 +310 +52 +-1 +242 +-1 +39 +341 +-1 +73 +341 +-1 +53 +152 +-1 +-1 +72 +478 +-1 +-1 +282 +201 +270 +63 +144 +-1 +418 +48 +350 +269 +-1 +54 +119 +547 +38 +143 +264 +-1 +499 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize3.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize3.txt new file mode 100644 index 0000000..77c483b --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize3.txt @@ -0,0 +1,300 @@ +209 +238 +240 +158 +76 +122 +-1 +-1 +86 +237 +105 +173 +104 +43 +38 +32 +97 +91 +25 +-1 +437 +-1 +47 +-1 +41 +-1 +63 +84 +30 +173 +237 +340 +17 +31 +128 +353 +298 +-1 +-1 +-1 +73 +111 +351 +-1 +282 +30 +167 +315 +133 +-1 +149 +119 +210 +50 +225 +304 +19 +-1 +149 +411 +69 +32 +223 +84 +134 +64 +-1 +75 +187 +276 +105 +118 +173 +-1 +146 +41 +41 +-1 +60 +-1 +206 +67 +-1 +73 +192 +244 +-1 +84 +42 +97 +95 +14 +-1 +104 +245 +149 +232 +213 +157 +-1 +48 +106 +90 +94 +91 +16 +102 +42 +83 +111 +250 +82 +469 +105 +133 +134 +57 +-1 +-1 +-1 +261 +53 +87 +101 +242 +74 +278 +145 +146 +84 +55 +98 +73 +-1 +125 +215 +219 +270 +231 +89 +459 +397 +153 +187 +14 +43 +25 +155 +54 +-1 +53 +84 +16 +229 +68 +-1 +151 +329 +-1 +126 +54 +48 +14 +372 +56 +-1 +33 +32 +135 +249 +285 +129 +81 +-1 +154 +32 +104 +-1 +522 +444 +46 +21 +-1 +86 +-1 +47 +227 +101 +-1 +158 +18 +-1 +86 +133 +-1 +295 +34 +75 +106 +18 +23 +-1 +190 +-1 +161 +147 +57 +109 +76 +109 +242 +90 +53 +-1 +152 +237 +41 +285 +242 +320 +115 +100 +148 +-1 +59 +-1 +176 +127 +75 +-1 +127 +197 +47 +127 +62 +221 +-1 +308 +255 +103 +248 +-1 +-1 +76 +-1 +204 +209 +179 +62 +141 +74 +52 +215 +321 +82 +27 +425 +433 +88 +389 +224 +-1 +247 +14 +27 +145 +287 +52 +67 +50 +251 +43 +164 +-1 +-1 +354 +-1 +47 +61 +74 +173 +197 +161 +78 +509 +222 +-1 +115 +313 +481 +38 +105 +-1 +-1 +243 +-1 +-1 +16 +192 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize4.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize4.txt new file mode 100644 index 0000000..0857f29 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize4.txt @@ -0,0 +1,300 @@ +45 +167 +182 +73 +-1 +-1 +18 +38 +70 +145 +50 +-1 +17 +15 +37 +388 +289 +176 +-1 +197 +55 +80 +132 +-1 +30 +-1 +82 +317 +62 +165 +165 +-1 +191 +-1 +156 +275 +34 +192 +81 +82 +93 +59 +153 +-1 +41 +88 +82 +160 +55 +182 +-1 +55 +417 +-1 +-1 +143 +52 +23 +17 +86 +-1 +20 +-1 +-1 +542 +158 +44 +14 +124 +69 +84 +41 +-1 +116 +139 +90 +69 +161 +52 +121 +133 +220 +347 +-1 +67 +390 +318 +40 +54 +40 +-1 +172 +175 +207 +136 +17 +28 +-1 +28 +68 +82 +15 +237 +25 +-1 +115 +86 +49 +402 +163 +80 +97 +229 +16 +90 +111 +176 +112 +14 +276 +47 +48 +94 +146 +137 +30 +138 +-1 +35 +207 +-1 +20 +23 +112 +316 +133 +52 +43 +44 +70 +16 +147 +37 +106 +127 +568 +190 +205 +47 +-1 +20 +43 +37 +63 +-1 +16 +429 +72 +89 +-1 +202 +169 +275 +107 +118 +119 +221 +48 +87 +30 +-1 +53 +-1 +23 +194 +164 +-1 +15 +94 +90 +213 +142 +308 +251 +23 +198 +78 +254 +382 +-1 +302 +-1 +66 +44 +63 +80 +101 +134 +377 +54 +16 +-1 +119 +55 +191 +-1 +235 +177 +-1 +30 +105 +147 +184 +79 +-1 +45 +82 +181 +359 +55 +40 +44 +47 +60 +45 +72 +248 +-1 +-1 +226 +112 +76 +107 +165 +-1 +113 +-1 +-1 +94 +588 +-1 +526 +153 +160 +160 +147 +139 +-1 +140 +72 +15 +-1 +51 +-1 +40 +54 +28 +200 +76 +-1 +383 +270 +141 +202 +418 +106 +189 +27 +113 +-1 +159 +224 +-1 +-1 +-1 +215 +117 +81 +349 +243 +75 +58 +181 +133 +19 +50 +17 +16 +249 +56 +36 +17 +211 +38 +210 +285 +199 +417 +104 +228 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize5.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize5.txt new file mode 100644 index 0000000..05f4538 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize5.txt @@ -0,0 +1,300 @@ +39 +48 +46 +121 +103 +67 +35 +184 +62 +71 +84 +132 +343 +-1 +-1 +40 +95 +216 +97 +355 +261 +45 +39 +16 +-1 +-1 +409 +38 +186 +213 +36 +425 +128 +90 +-1 +-1 +126 +57 +39 +24 +140 +-1 +208 +-1 +-1 +122 +21 +-1 +56 +53 +103 +33 +182 +78 +-1 +84 +229 +110 +32 +319 +288 +307 +535 +51 +98 +151 +43 +188 +212 +138 +-1 +49 +109 +36 +223 +310 +155 +67 +104 +137 +213 +35 +134 +-1 +100 +120 +56 +80 +162 +128 +126 +451 +54 +115 +121 +17 +191 +308 +339 +41 +16 +102 +41 +342 +98 +19 +42 +79 +282 +-1 +50 +140 +119 +85 +14 +26 +81 +500 +34 +136 +247 +-1 +140 +151 +548 +137 +43 +16 +63 +-1 +27 +-1 +86 +31 +118 +334 +215 +154 +105 +48 +247 +243 +45 +40 +136 +-1 +188 +-1 +75 +189 +-1 +19 +26 +28 +23 +47 +57 +187 +32 +44 +38 +280 +69 +407 +48 +198 +97 +192 +15 +34 +-1 +243 +29 +62 +21 +38 +74 +136 +396 +198 +326 +201 +199 +-1 +132 +25 +197 +16 +68 +15 +119 +72 +22 +150 +41 +197 +-1 +54 +62 +-1 +16 +-1 +15 +22 +35 +75 +85 +-1 +133 +141 +-1 +26 +144 +191 +58 +85 +106 +46 +230 +-1 +19 +220 +28 +-1 +108 +346 +-1 +23 +292 +37 +26 +40 +14 +57 +206 +22 +-1 +43 +193 +60 +93 +78 +53 +83 +-1 +43 +-1 +78 +103 +159 +16 +154 +206 +-1 +128 +380 +245 +-1 +15 +-1 +166 +263 +121 +-1 +43 +-1 +14 +167 +-1 +-1 +14 +153 +39 +48 +-1 +200 +37 +38 +302 +76 +448 +35 +55 +114 +-1 +194 +28 +-1 +49 +168 +56 +191 +461 +74 +169 +392 +243 +279 +511 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize6.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize6.txt new file mode 100644 index 0000000..ed94a53 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize6.txt @@ -0,0 +1,300 @@ +24 +19 +51 +332 +-1 +218 +25 +-1 +58 +102 +87 +-1 +58 +220 +-1 +333 +41 +45 +61 +179 +410 +58 +102 +-1 +57 +217 +436 +66 +46 +294 +497 +87 +24 +-1 +68 +227 +39 +220 +92 +16 +221 +22 +-1 +218 +31 +38 +345 +-1 +45 +44 +42 +429 +22 +81 +-1 +75 +89 +233 +64 +37 +56 +71 +128 +86 +39 +35 +257 +23 +165 +53 +64 +104 +-1 +110 +21 +87 +-1 +39 +105 +31 +230 +-1 +259 +-1 +-1 +76 +-1 +78 +335 +228 +-1 +29 +-1 +185 +29 +182 +157 +49 +525 +31 +43 +570 +69 +229 +95 +233 +189 +46 +31 +92 +107 +25 +-1 +65 +196 +20 +-1 +78 +116 +162 +186 +48 +28 +44 +202 +272 +-1 +186 +129 +30 +40 +166 +77 +-1 +32 +155 +39 +478 +-1 +34 +188 +102 +-1 +-1 +24 +14 +197 +-1 +80 +40 +-1 +60 +134 +28 +67 +26 +-1 +92 +72 +61 +-1 +94 +141 +154 +-1 +-1 +93 +198 +187 +310 +77 +286 +139 +43 +486 +100 +162 +220 +62 +272 +362 +116 +230 +95 +15 +186 +107 +58 +15 +110 +-1 +14 +22 +-1 +-1 +194 +20 +30 +-1 +74 +182 +186 +-1 +98 +47 +-1 +14 +91 +130 +111 +18 +-1 +169 +44 +18 +95 +-1 +61 +228 +76 +46 +105 +202 +17 +43 +222 +16 +102 +46 +-1 +-1 +112 +155 +184 +214 +43 +207 +245 +116 +144 +94 +135 +28 +-1 +64 +76 +90 +43 +174 +-1 +14 +143 +98 +50 +44 +-1 +28 +37 +-1 +94 +207 +-1 +95 +175 +-1 +-1 +15 +83 +57 +150 +356 +448 +52 +36 +200 +98 +24 +18 +34 +197 +48 +14 +76 +24 +28 +194 +-1 +-1 +78 +293 +141 +261 +243 +74 +130 +118 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize7.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize7.txt new file mode 100644 index 0000000..396e411 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize7.txt @@ -0,0 +1,300 @@ +42 +21 +76 +139 +59 +181 +63 +244 +35 +57 +193 +-1 +22 +-1 +-1 +217 +288 +55 +71 +204 +-1 +251 +62 +-1 +82 +-1 +224 +98 +172 +36 +589 +-1 +203 +22 +30 +93 +-1 +79 +233 +121 +55 +44 +54 +174 +538 +-1 +127 +-1 +61 +219 +-1 +193 +82 +-1 +-1 +-1 +244 +141 +139 +37 +23 +-1 +262 +87 +255 +-1 +205 +27 +42 +77 +-1 +156 +15 +28 +-1 +142 +-1 +248 +45 +30 +-1 +355 +34 +-1 +393 +40 +20 +187 +177 +24 +-1 +27 +-1 +347 +14 +-1 +-1 +349 +95 +164 +101 +-1 +-1 +218 +77 +37 +-1 +-1 +475 +103 +186 +475 +110 +-1 +36 +154 +155 +122 +95 +-1 +140 +164 +187 +185 +153 +-1 +85 +255 +137 +249 +134 +152 +498 +18 +24 +172 +34 +171 +-1 +-1 +76 +42 +14 +-1 +-1 +-1 +295 +40 +141 +-1 +178 +177 +35 +167 +-1 +60 +-1 +79 +162 +146 +149 +198 +53 +387 +-1 +65 +-1 +-1 +-1 +122 +65 +100 +38 +49 +388 +179 +266 +-1 +48 +504 +154 +47 +-1 +42 +-1 +-1 +38 +135 +90 +122 +-1 +168 +65 +92 +65 +42 +218 +47 +177 +22 +-1 +124 +-1 +-1 +236 +60 +132 +105 +83 +-1 +119 +-1 +35 +38 +21 +-1 +120 +16 +255 +-1 +-1 +143 +-1 +207 +49 +32 +141 +525 +88 +-1 +67 +309 +-1 +-1 +236 +200 +75 +-1 +191 +64 +-1 +72 +262 +61 +19 +-1 +365 +111 +-1 +229 +173 +100 +112 +91 +-1 +70 +240 +66 +14 +122 +137 +196 +151 +202 +176 +-1 +44 +49 +51 +143 +57 +162 +-1 +241 +21 +169 +106 +20 +-1 +210 +65 +127 +472 +97 +-1 +-1 +-1 +63 +54 +109 +143 +147 +49 +38 +20 +171 +58 +258 +215 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize8.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize8.txt new file mode 100644 index 0000000..cf940ac --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize8.txt @@ -0,0 +1,300 @@ +62 +397 +37 +25 +-1 +-1 +40 +170 +169 +20 +76 +74 +61 +187 +174 +-1 +167 +228 +28 +-1 +14 +86 +256 +27 +-1 +540 +77 +14 +-1 +152 +174 +-1 +390 +43 +77 +91 +20 +52 +151 +228 +-1 +25 +-1 +-1 +27 +-1 +56 +336 +76 +63 +118 +64 +508 +118 +140 +-1 +60 +-1 +-1 +95 +84 +67 +90 +59 +243 +191 +16 +34 +242 +41 +91 +112 +109 +47 +15 +132 +251 +35 +69 +55 +95 +47 +97 +164 +15 +394 +219 +432 +374 +328 +15 +-1 +21 +64 +194 +39 +59 +223 +15 +14 +102 +104 +84 +273 +101 +49 +61 +99 +-1 +41 +51 +37 +-1 +115 +44 +329 +425 +51 +165 +41 +132 +88 +15 +-1 +90 +139 +24 +36 +31 +185 +254 +52 +-1 +161 +116 +66 +238 +194 +193 +60 +90 +-1 +25 +64 +135 +465 +96 +-1 +182 +588 +218 +190 +73 +-1 +24 +210 +18 +-1 +53 +335 +63 +-1 +-1 +313 +116 +71 +14 +85 +74 +-1 +31 +-1 +53 +108 +39 +35 +82 +-1 +62 +312 +65 +118 +14 +33 +240 +66 +58 +29 +70 +29 +85 +220 +23 +39 +92 +55 +15 +16 +219 +24 +-1 +101 +270 +458 +78 +77 +115 +409 +-1 +-1 +152 +192 +23 +163 +15 +34 +111 +592 +408 +71 +128 +190 +-1 +62 +-1 +-1 +81 +136 +31 +269 +14 +-1 +48 +-1 +35 +15 +-1 +64 +196 +117 +32 +48 +125 +64 +252 +-1 +75 +14 +-1 +60 +525 +22 +221 +71 +42 +59 +-1 +174 +152 +206 +136 +259 +162 +39 +-1 +-1 +37 +34 +34 +21 +267 +40 +214 +31 +20 +73 +34 +415 +38 +71 +49 +48 +150 +198 +-1 +-1 +66 +-1 +195 +153 +34 +-1 +135 +-1 +-1 +25 +103 +81 +15 +109 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize9.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize9.txt new file mode 100644 index 0000000..ddd5375 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/howManyGenerations_5x5_300_600gen_k8popsize9.txt @@ -0,0 +1,300 @@ +46 +71 +20 +138 +57 +14 +52 +118 +166 +36 +192 +237 +-1 +-1 +146 +90 +161 +41 +48 +-1 +-1 +425 +29 +-1 +51 +171 +-1 +240 +98 +35 +559 +-1 +44 +-1 +40 +25 +73 +290 +45 +112 +137 +17 +89 +68 +36 +40 +51 +248 +123 +70 +154 +117 +220 +163 +106 +39 +72 +190 +134 +266 +36 +28 +91 +16 +24 +119 +48 +-1 +86 +43 +76 +213 +55 +92 +19 +29 +295 +69 +437 +23 +109 +143 +129 +28 +26 +209 +87 +193 +66 +45 +424 +61 +-1 +45 +-1 +316 +41 +84 +373 +105 +35 +188 +39 +32 +56 +174 +47 +180 +152 +26 +249 +-1 +-1 +62 +45 +63 +259 +-1 +57 +119 +68 +14 +108 +64 +364 +70 +16 +315 +23 +188 +327 +25 +228 +58 +55 +235 +599 +-1 +113 +29 +181 +-1 +167 +178 +148 +25 +137 +77 +41 +143 +33 +-1 +-1 +28 +58 +73 +-1 +30 +225 +555 +31 +-1 +368 +17 +149 +64 +461 +-1 +30 +81 +-1 +37 +85 +32 +64 +-1 +52 +271 +186 +139 +84 +-1 +244 +156 +-1 +16 +204 +-1 +-1 +-1 +26 +87 +14 +89 +85 +87 +79 +56 +-1 +-1 +299 +-1 +45 +80 +204 +34 +45 +80 +43 +64 +158 +65 +311 +179 +296 +142 +66 +-1 +80 +402 +34 +175 +148 +174 +144 +-1 +40 +226 +60 +-1 +144 +-1 +321 +65 +26 +100 +448 +76 +14 +54 +20 +235 +218 +78 +74 +65 +22 +153 +-1 +322 +-1 +64 +169 +248 +67 +68 +42 +140 +207 +403 +86 +122 +-1 +-1 +180 +112 +80 +-1 +-1 +247 +199 +102 +-1 +-1 +35 +52 +28 +70 +-1 +51 +34 +60 +45 +79 +158 +71 +291 +-1 +-1 +29 +137 +176 +43 +176 +81 +172 +561 +58 +250 +133 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_1000_600gen_k8popsize1.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_1000_600gen_k8popsize1.txt new file mode 100644 index 0000000..d6753f6 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_1000_600gen_k8popsize1.txt @@ -0,0 +1,1000 @@ +316 +136 +21 +-1 +123 +-1 +123 +286 +516 +-1 +-1 +241 +110 +133 +242 +189 +495 +-1 +76 +80 +-1 +149 +44 +-1 +-1 +140 +-1 +126 +-1 +302 +271 +171 +-1 +-1 +39 +-1 +36 +138 +357 +142 +-1 +149 +350 +260 +322 +125 +66 +60 +-1 +29 +192 +-1 +140 +105 +134 +40 +57 +121 +233 +-1 +-1 +204 +-1 +-1 +222 +62 +108 +24 +42 +-1 +123 +143 +388 +354 +257 +192 +95 +-1 +241 +186 +482 +59 +62 +56 +52 +249 +-1 +123 +-1 +-1 +-1 +94 +102 +310 +94 +187 +174 +169 +230 +174 +530 +-1 +409 +242 +-1 +175 +-1 +283 +-1 +61 +-1 +177 +374 +437 +91 +207 +20 +219 +139 +53 +55 +148 +-1 +35 +199 +-1 +345 +-1 +128 +212 +384 +-1 +154 +20 +50 +155 +-1 +548 +197 +-1 +-1 +134 +25 +513 +105 +143 +237 +231 +-1 +234 +264 +113 +-1 +271 +-1 +320 +-1 +-1 +352 +319 +174 +-1 +-1 +142 +398 +-1 +332 +57 +425 +-1 +-1 +403 +406 +85 +145 +-1 +-1 +464 +129 +-1 +154 +197 +-1 +197 +295 +232 +-1 +-1 +141 +-1 +178 +380 +102 +38 +315 +161 +-1 +218 +127 +376 +211 +252 +140 +298 +-1 +146 +52 +100 +112 +333 +-1 +321 +402 +-1 +61 +22 +58 +193 +191 +-1 +18 +283 +-1 +169 +252 +230 +-1 +234 +31 +182 +88 +257 +166 +116 +367 +134 +104 +103 +-1 +-1 +363 +-1 +179 +33 +111 +-1 +199 +444 +186 +-1 +537 +427 +593 +218 +102 +197 +-1 +360 +83 +28 +39 +366 +21 +190 +402 +134 +56 +166 +-1 +317 +235 +175 +54 +273 +60 +186 +313 +175 +201 +234 +89 +199 +140 +457 +-1 +170 +178 +229 +351 +26 +169 +103 +-1 +263 +169 +119 +564 +461 +262 +156 +289 +174 +91 +109 +383 +262 +-1 +184 +38 +-1 +-1 +281 +297 +152 +196 +177 +-1 +124 +67 +283 +247 +-1 +65 +-1 +68 +355 +276 +120 +260 +222 +-1 +128 +261 +317 +111 +262 +-1 +262 +-1 +90 +203 +124 +171 +193 +-1 +-1 +153 +292 +367 +37 +142 +234 +208 +388 +340 +96 +335 +269 +429 +41 +175 +312 +309 +185 +-1 +269 +494 +384 +365 +-1 +33 +-1 +191 +587 +-1 +-1 +101 +197 +307 +506 +268 +109 +242 +460 +213 +76 +342 +115 +-1 +119 +-1 +-1 +134 +182 +367 +-1 +144 +75 +231 +-1 +119 +431 +338 +32 +-1 +-1 +147 +-1 +237 +128 +350 +196 +-1 +283 +308 +585 +-1 +236 +-1 +174 +395 +-1 +110 +189 +-1 +57 +318 +-1 +142 +398 +201 +-1 +-1 +466 +234 +82 +132 +69 +231 +-1 +54 +-1 +193 +202 +95 +-1 +-1 +367 +177 +144 +355 +57 +-1 +111 +150 +137 +146 +410 +149 +389 +-1 +161 +21 +260 +385 +215 +-1 +332 +147 +-1 +391 +-1 +91 +-1 +75 +270 +413 +-1 +-1 +-1 +150 +231 +427 +201 +-1 +191 +-1 +189 +-1 +25 +126 +379 +89 +78 +162 +-1 +429 +415 +204 +218 +59 +180 +-1 +-1 +586 +-1 +-1 +227 +475 +-1 +-1 +64 +218 +442 +128 +562 +198 +-1 +-1 +184 +207 +118 +329 +146 +343 +-1 +253 +199 +207 +97 +20 +233 +-1 +439 +18 +167 +146 +335 +-1 +82 +453 +-1 +-1 +69 +225 +-1 +-1 +204 +-1 +106 +186 +536 +143 +-1 +-1 +165 +-1 +224 +116 +191 +379 +284 +393 +-1 +94 +-1 +-1 +92 +-1 +128 +-1 +183 +-1 +196 +236 +-1 +92 +398 +291 +-1 +461 +-1 +-1 +-1 +283 +53 +114 +199 +143 +223 +577 +-1 +276 +126 +95 +133 +314 +120 +202 +291 +138 +369 +-1 +136 +228 +-1 +153 +367 +46 +137 +146 +48 +223 +-1 +227 +108 +143 +-1 +488 +89 +290 +-1 +135 +278 +-1 +-1 +262 +364 +-1 +292 +197 +-1 +-1 +-1 +235 +115 +176 +302 +-1 +247 +-1 +90 +59 +316 +250 +-1 +159 +224 +107 +-1 +-1 +52 +97 +-1 +164 +151 +87 +40 +279 +305 +175 +122 +-1 +255 +477 +64 +-1 +107 +233 +242 +112 +-1 +189 +-1 +78 +343 +-1 +-1 +473 +59 +-1 +128 +-1 +32 +375 +384 +-1 +350 +-1 +114 +285 +74 +100 +196 +384 +112 +155 +30 +-1 +200 +495 +-1 +222 +517 +469 +140 +-1 +-1 +464 +126 +137 +-1 +123 +63 +279 +-1 +89 +-1 +397 +121 +587 +300 +521 +-1 +107 +260 +-1 +282 +136 +496 +253 +498 +178 +173 +139 +362 +180 +167 +167 +62 +90 +148 +-1 +200 +159 +318 +-1 +-1 +177 +-1 +84 +179 +461 +371 +-1 +-1 +335 +-1 +230 +394 +570 +253 +-1 +378 +251 +80 +-1 +429 +177 +195 +-1 +287 +156 +165 +20 +57 +238 +48 +-1 +-1 +252 +354 +71 +444 +-1 +432 +-1 +236 +-1 +-1 +431 +-1 +-1 +332 +-1 +-1 +390 +519 +286 +249 +-1 +-1 +-1 +101 +-1 +-1 +70 +35 +65 +34 +-1 +23 +266 +-1 +-1 +161 +571 +338 +-1 +161 +-1 +-1 +92 +349 +102 +415 +261 +105 +143 +79 +146 +350 +561 +184 +174 +-1 +251 +-1 +-1 +138 +229 +209 +-1 +87 +335 +-1 +274 +-1 +48 +68 +187 +-1 +-1 +23 +352 +116 +86 +385 +516 +402 +-1 +158 +174 +283 +-1 +491 +110 +90 +-1 +247 +403 +-1 +-1 +97 +-1 +85 +267 +-1 +-1 +149 +302 +301 +-1 +202 +200 +-1 +-1 +395 +266 +-1 +-1 +229 +507 +512 +-1 +-1 +345 +210 +88 +136 +358 +479 +-1 +62 +49 +93 +121 +298 +176 +230 +-1 +97 +217 +-1 +-1 +240 +296 +210 +223 +-1 +275 +47 +22 +342 +143 +96 +366 +76 +235 +262 +89 +401 +-1 +-1 +191 +120 +-1 +-1 +-1 +157 +49 +-1 +207 +233 +267 +235 +-1 +75 +197 +105 +178 +119 +-1 +38 +384 +288 +34 +92 +336 +-1 +98 +24 +185 +201 +199 +77 +99 +-1 +143 +-1 +65 +-1 +209 +94 +231 +148 +-1 +-1 +-1 +-1 +-1 +25 +-1 +-1 +-1 +400 +440 +17 +84 +17 +-1 +-1 +57 +-1 +270 +-1 +20 +589 +150 +242 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize10.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize10.txt new file mode 100644 index 0000000..1b15f4e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize10.txt @@ -0,0 +1,300 @@ +29 +134 +63 +138 +26 +-1 +44 +-1 +214 +-1 +206 +83 +-1 +81 +33 +113 +42 +53 +17 +534 +72 +66 +113 +295 +209 +51 +21 +-1 +365 +59 +526 +222 +428 +223 +31 +260 +-1 +-1 +64 +324 +33 +182 +75 +46 +201 +31 +175 +74 +56 +18 +174 +66 +-1 +214 +25 +-1 +18 +113 +-1 +26 +38 +30 +58 +294 +-1 +48 +105 +137 +96 +34 +14 +90 +131 +364 +121 +-1 +198 +337 +37 +23 +16 +82 +113 +35 +-1 +128 +236 +235 +101 +276 +128 +47 +246 +63 +59 +82 +-1 +70 +147 +70 +32 +-1 +-1 +18 +61 +35 +57 +78 +33 +467 +125 +59 +-1 +119 +64 +185 +-1 +60 +35 +54 +147 +-1 +188 +349 +158 +146 +171 +28 +237 +27 +-1 +250 +529 +180 +47 +99 +387 +53 +19 +-1 +28 +298 +206 +41 +63 +19 +82 +202 +571 +60 +28 +47 +143 +230 +40 +-1 +149 +188 +179 +-1 +148 +70 +46 +179 +33 +30 +182 +17 +66 +29 +39 +193 +15 +73 +33 +96 +58 +148 +56 +105 +67 +61 +101 +-1 +49 +24 +152 +36 +21 +-1 +17 +14 +-1 +20 +27 +43 +119 +332 +73 +106 +27 +252 +143 +415 +28 +44 +147 +469 +303 +166 +189 +71 +-1 +105 +-1 +190 +88 +41 +-1 +27 +185 +116 +16 +103 +190 +26 +223 +412 +373 +26 +-1 +365 +139 +80 +300 +256 +-1 +45 +280 +51 +91 +15 +46 +91 +256 +-1 +53 +168 +188 +209 +-1 +38 +-1 +188 +237 +66 +-1 +46 +30 +-1 +184 +23 +82 +37 +25 +123 +84 +257 +195 +93 +-1 +14 +75 +522 +15 +-1 +83 +254 +213 +98 +115 +262 +200 +118 +100 +473 +60 +-1 +206 +15 +137 +-1 +268 +36 +68 +130 +-1 +-1 +75 +337 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize11.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize11.txt new file mode 100644 index 0000000..aa9075d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize11.txt @@ -0,0 +1,300 @@ +51 +155 +52 +102 +34 +74 +-1 +177 +52 +112 +-1 +119 +50 +115 +220 +136 +-1 +-1 +58 +18 +-1 +22 +96 +42 +22 +45 +144 +241 +75 +-1 +149 +14 +-1 +15 +452 +-1 +213 +93 +51 +-1 +-1 +41 +-1 +57 +-1 +-1 +85 +23 +439 +106 +45 +-1 +19 +33 +21 +29 +53 +15 +18 +36 +135 +-1 +43 +77 +16 +-1 +498 +20 +-1 +66 +105 +36 +109 +17 +190 +102 +231 +16 +132 +-1 +101 +515 +-1 +168 +230 +53 +128 +36 +95 +102 +61 +69 +42 +65 +72 +382 +42 +99 +34 +24 +80 +43 +-1 +419 +105 +219 +125 +-1 +108 +31 +37 +-1 +240 +77 +315 +23 +74 +-1 +58 +-1 +47 +204 +34 +63 +83 +249 +17 +67 +163 +22 +42 +47 +-1 +28 +142 +-1 +64 +207 +-1 +75 +81 +48 +148 +30 +44 +-1 +99 +19 +-1 +140 +50 +76 +185 +30 +-1 +99 +23 +67 +188 +96 +431 +116 +50 +48 +183 +-1 +303 +565 +60 +76 +27 +-1 +-1 +16 +36 +224 +78 +44 +50 +-1 +-1 +21 +144 +198 +189 +31 +281 +-1 +28 +-1 +172 +38 +40 +-1 +103 +49 +290 +242 +130 +-1 +-1 +72 +-1 +61 +36 +38 +250 +75 +-1 +-1 +-1 +33 +32 +46 +-1 +47 +26 +250 +82 +66 +74 +14 +47 +60 +133 +17 +98 +52 +-1 +-1 +135 +16 +25 +18 +-1 +14 +66 +-1 +20 +15 +159 +363 +246 +334 +190 +39 +31 +73 +-1 +33 +50 +330 +229 +-1 +15 +52 +-1 +91 +62 +547 +54 +102 +33 +58 +78 +23 +238 +183 +104 +-1 +-1 +24 +-1 +33 +116 +392 +-1 +156 +14 +178 +160 +-1 +161 +106 +326 +17 +65 +34 +254 +38 +-1 +54 +22 +216 +37 +168 +99 +47 +229 +342 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize12.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize12.txt new file mode 100644 index 0000000..6ef0fef --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize12.txt @@ -0,0 +1,300 @@ +377 +247 +-1 +-1 +45 +324 +348 +416 +51 +29 +63 +34 +147 +154 +30 +261 +-1 +51 +56 +198 +101 +35 +266 +107 +218 +-1 +85 +-1 +82 +231 +23 +245 +73 +65 +65 +455 +74 +14 +-1 +25 +124 +24 +-1 +200 +-1 +-1 +111 +186 +42 +180 +65 +-1 +73 +269 +62 +292 +114 +49 +88 +232 +27 +114 +-1 +125 +-1 +357 +60 +65 +164 +76 +-1 +21 +16 +367 +105 +20 +254 +70 +-1 +118 +-1 +43 +35 +-1 +14 +17 +116 +80 +40 +17 +28 +119 +23 +76 +-1 +102 +401 +89 +186 +30 +147 +52 +26 +81 +17 +16 +61 +120 +157 +358 +152 +311 +245 +-1 +87 +24 +-1 +43 +60 +67 +122 +88 +169 +35 +-1 +67 +16 +140 +75 +31 +-1 +186 +-1 +133 +59 +28 +36 +38 +88 +63 +28 +-1 +-1 +-1 +169 +23 +68 +56 +104 +-1 +18 +46 +48 +-1 +125 +24 +124 +182 +52 +276 +-1 +-1 +-1 +-1 +392 +93 +18 +88 +15 +51 +410 +210 +43 +102 +116 +54 +413 +50 +86 +-1 +56 +213 +59 +199 +42 +129 +-1 +-1 +67 +67 +35 +14 +31 +95 +45 +108 +79 +41 +93 +61 +44 +35 +-1 +75 +-1 +18 +81 +97 +22 +-1 +73 +147 +167 +69 +486 +-1 +175 +557 +32 +16 +26 +206 +66 +14 +73 +156 +-1 +26 +146 +21 +19 +74 +-1 +64 +273 +144 +-1 +49 +298 +46 +258 +37 +496 +75 +139 +519 +150 +82 +70 +87 +131 +241 +93 +-1 +182 +308 +52 +19 +59 +16 +76 +97 +116 +-1 +36 +-1 +111 +162 +-1 +140 +413 +370 +322 +64 +-1 +25 +47 +-1 +133 +-1 +205 +95 +94 +102 +14 +74 +47 +33 +-1 +26 +39 +48 +61 +134 +25 +-1 +232 +-1 +377 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize13.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize13.txt new file mode 100644 index 0000000..a69fe39 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize13.txt @@ -0,0 +1,300 @@ +25 +43 +189 +440 +527 +31 +106 +53 +91 +48 +109 +-1 +433 +97 +-1 +111 +-1 +65 +17 +25 +66 +46 +49 +61 +94 +189 +104 +222 +402 +96 +62 +-1 +28 +226 +193 +203 +189 +27 +120 +449 +123 +39 +112 +65 +18 +60 +44 +192 +29 +279 +41 +-1 +41 +44 +64 +32 +-1 +109 +28 +142 +96 +261 +-1 +28 +66 +145 +71 +94 +87 +72 +-1 +96 +-1 +49 +105 +490 +34 +-1 +81 +14 +-1 +445 +143 +277 +185 +14 +185 +33 +468 +190 +71 +190 +121 +58 +58 +76 +51 +-1 +38 +395 +75 +-1 +300 +23 +96 +-1 +42 +171 +62 +109 +24 +340 +-1 +23 +113 +135 +125 +51 +93 +271 +212 +38 +-1 +43 +114 +67 +190 +-1 +37 +-1 +368 +48 +23 +201 +-1 +104 +49 +-1 +35 +160 +527 +50 +314 +24 +71 +464 +34 +413 +74 +-1 +51 +-1 +38 +21 +86 +44 +71 +114 +60 +17 +112 +178 +177 +98 +67 +23 +240 +25 +-1 +132 +-1 +-1 +233 +14 +76 +125 +76 +152 +21 +36 +130 +68 +58 +217 +206 +287 +110 +53 +170 +20 +78 +193 +95 +208 +20 +507 +65 +187 +-1 +80 +122 +33 +19 +180 +259 +-1 +161 +121 +142 +47 +334 +-1 +-1 +-1 +65 +16 +17 +132 +67 +130 +126 +-1 +-1 +31 +69 +39 +47 +27 +74 +97 +69 +-1 +73 +22 +71 +43 +148 +385 +46 +38 +500 +28 +16 +188 +64 +14 +45 +27 +193 +-1 +-1 +34 +109 +404 +46 +103 +99 +68 +63 +110 +59 +43 +81 +105 +47 +-1 +-1 +34 +58 +69 +109 +40 +114 +50 +30 +123 +373 +149 +92 +120 +127 +76 +24 +98 +14 +67 +84 +147 +178 +52 +43 +109 +35 +326 +187 +-1 +346 +-1 +139 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize14.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize14.txt new file mode 100644 index 0000000..9fd40b0 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize14.txt @@ -0,0 +1,300 @@ +15 +16 +141 +165 +40 +177 +14 +-1 +107 +41 +-1 +-1 +92 +82 +33 +58 +114 +166 +91 +52 +151 +-1 +53 +262 +40 +42 +-1 +15 +591 +66 +-1 +54 +95 +93 +32 +16 +77 +54 +44 +89 +24 +146 +26 +181 +38 +59 +37 +-1 +-1 +146 +226 +571 +26 +202 +168 +148 +80 +42 +148 +-1 +44 +162 +-1 +97 +85 +61 +76 +-1 +26 +-1 +217 +269 +393 +46 +-1 +85 +132 +115 +476 +27 +86 +22 +-1 +-1 +58 +68 +-1 +54 +97 +138 +36 +109 +31 +183 +71 +33 +23 +332 +96 +90 +97 +15 +24 +88 +18 +33 +34 +188 +-1 +14 +308 +-1 +32 +15 +90 +73 +38 +-1 +-1 +74 +57 +204 +42 +65 +44 +-1 +49 +81 +22 +323 +14 +76 +43 +20 +39 +24 +131 +19 +192 +514 +120 +20 +589 +390 +-1 +15 +22 +95 +123 +32 +-1 +189 +50 +-1 +-1 +138 +84 +125 +26 +46 +-1 +155 +177 +114 +46 +109 +-1 +23 +-1 +20 +15 +363 +104 +60 +41 +183 +51 +145 +308 +-1 +22 +31 +-1 +-1 +16 +54 +206 +135 +276 +158 +51 +-1 +63 +40 +74 +150 +76 +209 +252 +-1 +29 +307 +26 +26 +306 +108 +41 +-1 +23 +34 +36 +-1 +36 +57 +43 +79 +126 +38 +99 +-1 +495 +69 +21 +23 +118 +15 +-1 +-1 +21 +70 +63 +-1 +108 +189 +36 +-1 +254 +-1 +300 +187 +202 +48 +64 +225 +-1 +22 +42 +39 +142 +69 +61 +28 +202 +142 +217 +187 +-1 +-1 +585 +53 +402 +83 +265 +65 +-1 +27 +-1 +102 +30 +42 +130 +117 +93 +31 +59 +38 +45 +111 +40 +-1 +300 +119 +110 +26 +19 +92 +403 +41 +79 +259 +119 +14 +122 +44 +40 +70 +44 +66 +235 +305 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize2.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize2.txt new file mode 100644 index 0000000..5aaceec --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize2.txt @@ -0,0 +1,300 @@ +88 +74 +-1 +-1 +173 +-1 +204 +100 +28 +-1 +236 +69 +-1 +199 +70 +142 +197 +28 +268 +170 +-1 +197 +50 +96 +169 +-1 +-1 +121 +58 +216 +92 +258 +-1 +93 +-1 +101 +49 +164 +243 +231 +56 +289 +54 +-1 +17 +129 +150 +140 +28 +59 +250 +73 +348 +258 +140 +129 +-1 +96 +29 +-1 +19 +75 +-1 +75 +-1 +171 +234 +83 +237 +85 +81 +-1 +-1 +64 +18 +229 +-1 +356 +344 +83 +142 +141 +58 +111 +64 +277 +190 +45 +54 +42 +110 +131 +310 +220 +217 +176 +37 +245 +44 +48 +-1 +86 +159 +233 +471 +25 +-1 +232 +242 +-1 +144 +49 +230 +-1 +57 +-1 +24 +105 +345 +312 +73 +557 +38 +-1 +131 +324 +44 +-1 +392 +72 +47 +-1 +28 +126 +-1 +122 +239 +-1 +-1 +46 +35 +148 +74 +103 +85 +239 +71 +256 +-1 +-1 +249 +72 +39 +211 +191 +113 +75 +105 +-1 +-1 +131 +410 +-1 +48 +158 +39 +90 +109 +-1 +82 +-1 +93 +236 +115 +249 +188 +211 +68 +-1 +-1 +102 +131 +75 +143 +77 +-1 +-1 +63 +315 +-1 +206 +216 +35 +-1 +49 +33 +257 +312 +69 +342 +265 +153 +244 +-1 +114 +444 +591 +107 +169 +97 +429 +475 +47 +-1 +52 +297 +128 +127 +98 +-1 +145 +178 +15 +284 +167 +-1 +242 +82 +53 +172 +-1 +106 +132 +127 +70 +184 +-1 +241 +27 +83 +-1 +206 +68 +201 +211 +23 +63 +64 +-1 +127 +146 +355 +61 +243 +-1 +198 +74 +24 +-1 +30 +148 +111 +310 +52 +-1 +242 +-1 +39 +341 +-1 +73 +341 +-1 +53 +152 +-1 +-1 +72 +478 +-1 +-1 +282 +201 +270 +63 +144 +-1 +418 +48 +350 +269 +-1 +54 +119 +547 +38 +143 +264 +-1 +499 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize3.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize3.txt new file mode 100644 index 0000000..77c483b --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize3.txt @@ -0,0 +1,300 @@ +209 +238 +240 +158 +76 +122 +-1 +-1 +86 +237 +105 +173 +104 +43 +38 +32 +97 +91 +25 +-1 +437 +-1 +47 +-1 +41 +-1 +63 +84 +30 +173 +237 +340 +17 +31 +128 +353 +298 +-1 +-1 +-1 +73 +111 +351 +-1 +282 +30 +167 +315 +133 +-1 +149 +119 +210 +50 +225 +304 +19 +-1 +149 +411 +69 +32 +223 +84 +134 +64 +-1 +75 +187 +276 +105 +118 +173 +-1 +146 +41 +41 +-1 +60 +-1 +206 +67 +-1 +73 +192 +244 +-1 +84 +42 +97 +95 +14 +-1 +104 +245 +149 +232 +213 +157 +-1 +48 +106 +90 +94 +91 +16 +102 +42 +83 +111 +250 +82 +469 +105 +133 +134 +57 +-1 +-1 +-1 +261 +53 +87 +101 +242 +74 +278 +145 +146 +84 +55 +98 +73 +-1 +125 +215 +219 +270 +231 +89 +459 +397 +153 +187 +14 +43 +25 +155 +54 +-1 +53 +84 +16 +229 +68 +-1 +151 +329 +-1 +126 +54 +48 +14 +372 +56 +-1 +33 +32 +135 +249 +285 +129 +81 +-1 +154 +32 +104 +-1 +522 +444 +46 +21 +-1 +86 +-1 +47 +227 +101 +-1 +158 +18 +-1 +86 +133 +-1 +295 +34 +75 +106 +18 +23 +-1 +190 +-1 +161 +147 +57 +109 +76 +109 +242 +90 +53 +-1 +152 +237 +41 +285 +242 +320 +115 +100 +148 +-1 +59 +-1 +176 +127 +75 +-1 +127 +197 +47 +127 +62 +221 +-1 +308 +255 +103 +248 +-1 +-1 +76 +-1 +204 +209 +179 +62 +141 +74 +52 +215 +321 +82 +27 +425 +433 +88 +389 +224 +-1 +247 +14 +27 +145 +287 +52 +67 +50 +251 +43 +164 +-1 +-1 +354 +-1 +47 +61 +74 +173 +197 +161 +78 +509 +222 +-1 +115 +313 +481 +38 +105 +-1 +-1 +243 +-1 +-1 +16 +192 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize4.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize4.txt new file mode 100644 index 0000000..0857f29 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize4.txt @@ -0,0 +1,300 @@ +45 +167 +182 +73 +-1 +-1 +18 +38 +70 +145 +50 +-1 +17 +15 +37 +388 +289 +176 +-1 +197 +55 +80 +132 +-1 +30 +-1 +82 +317 +62 +165 +165 +-1 +191 +-1 +156 +275 +34 +192 +81 +82 +93 +59 +153 +-1 +41 +88 +82 +160 +55 +182 +-1 +55 +417 +-1 +-1 +143 +52 +23 +17 +86 +-1 +20 +-1 +-1 +542 +158 +44 +14 +124 +69 +84 +41 +-1 +116 +139 +90 +69 +161 +52 +121 +133 +220 +347 +-1 +67 +390 +318 +40 +54 +40 +-1 +172 +175 +207 +136 +17 +28 +-1 +28 +68 +82 +15 +237 +25 +-1 +115 +86 +49 +402 +163 +80 +97 +229 +16 +90 +111 +176 +112 +14 +276 +47 +48 +94 +146 +137 +30 +138 +-1 +35 +207 +-1 +20 +23 +112 +316 +133 +52 +43 +44 +70 +16 +147 +37 +106 +127 +568 +190 +205 +47 +-1 +20 +43 +37 +63 +-1 +16 +429 +72 +89 +-1 +202 +169 +275 +107 +118 +119 +221 +48 +87 +30 +-1 +53 +-1 +23 +194 +164 +-1 +15 +94 +90 +213 +142 +308 +251 +23 +198 +78 +254 +382 +-1 +302 +-1 +66 +44 +63 +80 +101 +134 +377 +54 +16 +-1 +119 +55 +191 +-1 +235 +177 +-1 +30 +105 +147 +184 +79 +-1 +45 +82 +181 +359 +55 +40 +44 +47 +60 +45 +72 +248 +-1 +-1 +226 +112 +76 +107 +165 +-1 +113 +-1 +-1 +94 +588 +-1 +526 +153 +160 +160 +147 +139 +-1 +140 +72 +15 +-1 +51 +-1 +40 +54 +28 +200 +76 +-1 +383 +270 +141 +202 +418 +106 +189 +27 +113 +-1 +159 +224 +-1 +-1 +-1 +215 +117 +81 +349 +243 +75 +58 +181 +133 +19 +50 +17 +16 +249 +56 +36 +17 +211 +38 +210 +285 +199 +417 +104 +228 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize5.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize5.txt new file mode 100644 index 0000000..05f4538 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize5.txt @@ -0,0 +1,300 @@ +39 +48 +46 +121 +103 +67 +35 +184 +62 +71 +84 +132 +343 +-1 +-1 +40 +95 +216 +97 +355 +261 +45 +39 +16 +-1 +-1 +409 +38 +186 +213 +36 +425 +128 +90 +-1 +-1 +126 +57 +39 +24 +140 +-1 +208 +-1 +-1 +122 +21 +-1 +56 +53 +103 +33 +182 +78 +-1 +84 +229 +110 +32 +319 +288 +307 +535 +51 +98 +151 +43 +188 +212 +138 +-1 +49 +109 +36 +223 +310 +155 +67 +104 +137 +213 +35 +134 +-1 +100 +120 +56 +80 +162 +128 +126 +451 +54 +115 +121 +17 +191 +308 +339 +41 +16 +102 +41 +342 +98 +19 +42 +79 +282 +-1 +50 +140 +119 +85 +14 +26 +81 +500 +34 +136 +247 +-1 +140 +151 +548 +137 +43 +16 +63 +-1 +27 +-1 +86 +31 +118 +334 +215 +154 +105 +48 +247 +243 +45 +40 +136 +-1 +188 +-1 +75 +189 +-1 +19 +26 +28 +23 +47 +57 +187 +32 +44 +38 +280 +69 +407 +48 +198 +97 +192 +15 +34 +-1 +243 +29 +62 +21 +38 +74 +136 +396 +198 +326 +201 +199 +-1 +132 +25 +197 +16 +68 +15 +119 +72 +22 +150 +41 +197 +-1 +54 +62 +-1 +16 +-1 +15 +22 +35 +75 +85 +-1 +133 +141 +-1 +26 +144 +191 +58 +85 +106 +46 +230 +-1 +19 +220 +28 +-1 +108 +346 +-1 +23 +292 +37 +26 +40 +14 +57 +206 +22 +-1 +43 +193 +60 +93 +78 +53 +83 +-1 +43 +-1 +78 +103 +159 +16 +154 +206 +-1 +128 +380 +245 +-1 +15 +-1 +166 +263 +121 +-1 +43 +-1 +14 +167 +-1 +-1 +14 +153 +39 +48 +-1 +200 +37 +38 +302 +76 +448 +35 +55 +114 +-1 +194 +28 +-1 +49 +168 +56 +191 +461 +74 +169 +392 +243 +279 +511 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize6.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize6.txt new file mode 100644 index 0000000..ed94a53 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize6.txt @@ -0,0 +1,300 @@ +24 +19 +51 +332 +-1 +218 +25 +-1 +58 +102 +87 +-1 +58 +220 +-1 +333 +41 +45 +61 +179 +410 +58 +102 +-1 +57 +217 +436 +66 +46 +294 +497 +87 +24 +-1 +68 +227 +39 +220 +92 +16 +221 +22 +-1 +218 +31 +38 +345 +-1 +45 +44 +42 +429 +22 +81 +-1 +75 +89 +233 +64 +37 +56 +71 +128 +86 +39 +35 +257 +23 +165 +53 +64 +104 +-1 +110 +21 +87 +-1 +39 +105 +31 +230 +-1 +259 +-1 +-1 +76 +-1 +78 +335 +228 +-1 +29 +-1 +185 +29 +182 +157 +49 +525 +31 +43 +570 +69 +229 +95 +233 +189 +46 +31 +92 +107 +25 +-1 +65 +196 +20 +-1 +78 +116 +162 +186 +48 +28 +44 +202 +272 +-1 +186 +129 +30 +40 +166 +77 +-1 +32 +155 +39 +478 +-1 +34 +188 +102 +-1 +-1 +24 +14 +197 +-1 +80 +40 +-1 +60 +134 +28 +67 +26 +-1 +92 +72 +61 +-1 +94 +141 +154 +-1 +-1 +93 +198 +187 +310 +77 +286 +139 +43 +486 +100 +162 +220 +62 +272 +362 +116 +230 +95 +15 +186 +107 +58 +15 +110 +-1 +14 +22 +-1 +-1 +194 +20 +30 +-1 +74 +182 +186 +-1 +98 +47 +-1 +14 +91 +130 +111 +18 +-1 +169 +44 +18 +95 +-1 +61 +228 +76 +46 +105 +202 +17 +43 +222 +16 +102 +46 +-1 +-1 +112 +155 +184 +214 +43 +207 +245 +116 +144 +94 +135 +28 +-1 +64 +76 +90 +43 +174 +-1 +14 +143 +98 +50 +44 +-1 +28 +37 +-1 +94 +207 +-1 +95 +175 +-1 +-1 +15 +83 +57 +150 +356 +448 +52 +36 +200 +98 +24 +18 +34 +197 +48 +14 +76 +24 +28 +194 +-1 +-1 +78 +293 +141 +261 +243 +74 +130 +118 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize7.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize7.txt new file mode 100644 index 0000000..396e411 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize7.txt @@ -0,0 +1,300 @@ +42 +21 +76 +139 +59 +181 +63 +244 +35 +57 +193 +-1 +22 +-1 +-1 +217 +288 +55 +71 +204 +-1 +251 +62 +-1 +82 +-1 +224 +98 +172 +36 +589 +-1 +203 +22 +30 +93 +-1 +79 +233 +121 +55 +44 +54 +174 +538 +-1 +127 +-1 +61 +219 +-1 +193 +82 +-1 +-1 +-1 +244 +141 +139 +37 +23 +-1 +262 +87 +255 +-1 +205 +27 +42 +77 +-1 +156 +15 +28 +-1 +142 +-1 +248 +45 +30 +-1 +355 +34 +-1 +393 +40 +20 +187 +177 +24 +-1 +27 +-1 +347 +14 +-1 +-1 +349 +95 +164 +101 +-1 +-1 +218 +77 +37 +-1 +-1 +475 +103 +186 +475 +110 +-1 +36 +154 +155 +122 +95 +-1 +140 +164 +187 +185 +153 +-1 +85 +255 +137 +249 +134 +152 +498 +18 +24 +172 +34 +171 +-1 +-1 +76 +42 +14 +-1 +-1 +-1 +295 +40 +141 +-1 +178 +177 +35 +167 +-1 +60 +-1 +79 +162 +146 +149 +198 +53 +387 +-1 +65 +-1 +-1 +-1 +122 +65 +100 +38 +49 +388 +179 +266 +-1 +48 +504 +154 +47 +-1 +42 +-1 +-1 +38 +135 +90 +122 +-1 +168 +65 +92 +65 +42 +218 +47 +177 +22 +-1 +124 +-1 +-1 +236 +60 +132 +105 +83 +-1 +119 +-1 +35 +38 +21 +-1 +120 +16 +255 +-1 +-1 +143 +-1 +207 +49 +32 +141 +525 +88 +-1 +67 +309 +-1 +-1 +236 +200 +75 +-1 +191 +64 +-1 +72 +262 +61 +19 +-1 +365 +111 +-1 +229 +173 +100 +112 +91 +-1 +70 +240 +66 +14 +122 +137 +196 +151 +202 +176 +-1 +44 +49 +51 +143 +57 +162 +-1 +241 +21 +169 +106 +20 +-1 +210 +65 +127 +472 +97 +-1 +-1 +-1 +63 +54 +109 +143 +147 +49 +38 +20 +171 +58 +258 +215 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize8.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize8.txt new file mode 100644 index 0000000..cf940ac --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize8.txt @@ -0,0 +1,300 @@ +62 +397 +37 +25 +-1 +-1 +40 +170 +169 +20 +76 +74 +61 +187 +174 +-1 +167 +228 +28 +-1 +14 +86 +256 +27 +-1 +540 +77 +14 +-1 +152 +174 +-1 +390 +43 +77 +91 +20 +52 +151 +228 +-1 +25 +-1 +-1 +27 +-1 +56 +336 +76 +63 +118 +64 +508 +118 +140 +-1 +60 +-1 +-1 +95 +84 +67 +90 +59 +243 +191 +16 +34 +242 +41 +91 +112 +109 +47 +15 +132 +251 +35 +69 +55 +95 +47 +97 +164 +15 +394 +219 +432 +374 +328 +15 +-1 +21 +64 +194 +39 +59 +223 +15 +14 +102 +104 +84 +273 +101 +49 +61 +99 +-1 +41 +51 +37 +-1 +115 +44 +329 +425 +51 +165 +41 +132 +88 +15 +-1 +90 +139 +24 +36 +31 +185 +254 +52 +-1 +161 +116 +66 +238 +194 +193 +60 +90 +-1 +25 +64 +135 +465 +96 +-1 +182 +588 +218 +190 +73 +-1 +24 +210 +18 +-1 +53 +335 +63 +-1 +-1 +313 +116 +71 +14 +85 +74 +-1 +31 +-1 +53 +108 +39 +35 +82 +-1 +62 +312 +65 +118 +14 +33 +240 +66 +58 +29 +70 +29 +85 +220 +23 +39 +92 +55 +15 +16 +219 +24 +-1 +101 +270 +458 +78 +77 +115 +409 +-1 +-1 +152 +192 +23 +163 +15 +34 +111 +592 +408 +71 +128 +190 +-1 +62 +-1 +-1 +81 +136 +31 +269 +14 +-1 +48 +-1 +35 +15 +-1 +64 +196 +117 +32 +48 +125 +64 +252 +-1 +75 +14 +-1 +60 +525 +22 +221 +71 +42 +59 +-1 +174 +152 +206 +136 +259 +162 +39 +-1 +-1 +37 +34 +34 +21 +267 +40 +214 +31 +20 +73 +34 +415 +38 +71 +49 +48 +150 +198 +-1 +-1 +66 +-1 +195 +153 +34 +-1 +135 +-1 +-1 +25 +103 +81 +15 +109 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize9.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize9.txt new file mode 100644 index 0000000..ddd5375 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize9.txt @@ -0,0 +1,300 @@ +46 +71 +20 +138 +57 +14 +52 +118 +166 +36 +192 +237 +-1 +-1 +146 +90 +161 +41 +48 +-1 +-1 +425 +29 +-1 +51 +171 +-1 +240 +98 +35 +559 +-1 +44 +-1 +40 +25 +73 +290 +45 +112 +137 +17 +89 +68 +36 +40 +51 +248 +123 +70 +154 +117 +220 +163 +106 +39 +72 +190 +134 +266 +36 +28 +91 +16 +24 +119 +48 +-1 +86 +43 +76 +213 +55 +92 +19 +29 +295 +69 +437 +23 +109 +143 +129 +28 +26 +209 +87 +193 +66 +45 +424 +61 +-1 +45 +-1 +316 +41 +84 +373 +105 +35 +188 +39 +32 +56 +174 +47 +180 +152 +26 +249 +-1 +-1 +62 +45 +63 +259 +-1 +57 +119 +68 +14 +108 +64 +364 +70 +16 +315 +23 +188 +327 +25 +228 +58 +55 +235 +599 +-1 +113 +29 +181 +-1 +167 +178 +148 +25 +137 +77 +41 +143 +33 +-1 +-1 +28 +58 +73 +-1 +30 +225 +555 +31 +-1 +368 +17 +149 +64 +461 +-1 +30 +81 +-1 +37 +85 +32 +64 +-1 +52 +271 +186 +139 +84 +-1 +244 +156 +-1 +16 +204 +-1 +-1 +-1 +26 +87 +14 +89 +85 +87 +79 +56 +-1 +-1 +299 +-1 +45 +80 +204 +34 +45 +80 +43 +64 +158 +65 +311 +179 +296 +142 +66 +-1 +80 +402 +34 +175 +148 +174 +144 +-1 +40 +226 +60 +-1 +144 +-1 +321 +65 +26 +100 +448 +76 +14 +54 +20 +235 +218 +78 +74 +65 +22 +153 +-1 +322 +-1 +64 +169 +248 +67 +68 +42 +140 +207 +403 +86 +122 +-1 +-1 +180 +112 +80 +-1 +-1 +247 +199 +102 +-1 +-1 +35 +52 +28 +70 +-1 +51 +34 +60 +45 +79 +158 +71 +291 +-1 +-1 +29 +137 +176 +43 +176 +81 +172 +561 +58 +250 +133 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/docker-compose.yml b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/docker-compose.yml new file mode 100644 index 0000000..107fc50 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/docker-compose.yml @@ -0,0 +1,21 @@ +services: + major-miner: + build: . + container_name: major-miner + environment: + CORE_PERCENTAGE: 90 + MAX_MUTATION_TRIALS: 30 + PROB_EXTEND_TO_FREE_NEIGHBOR: 0.3 + MAX_TOTAL: 1000 + MAX_GENERATIONS: 600 + PROB_REMOVE_REDUNDANCY: 0.01 + GRID_M: 5 + GRID_N: 5 + K_GRAPH: 8 + POPSIZE: 6 + PROB_STEPS: 20 + + volumes: + - type: bind + source: ./out + target: /app/out diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/evolution_dockerized.py b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/evolution_dockerized.py new file mode 100644 index 0000000..2efaa8c --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/evolution_dockerized.py @@ -0,0 +1,146 @@ +# Move this file to src/solver to start +# Disable logger! + +import logging +import multiprocessing +import os +import shutil +import time +from functools import partial +from random import random +from typing import Optional + +import numpy as np +from src.drawing.draw import DrawEmbedding +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + +################################# Params ####################################### + +max_total = int(os.getenv('MAX_TOTAL', 300)) +max_generations = int(os.getenv('MAX_GENERATIONS', 600)) +remove_redundancy_probability = float(os.getenv('PROB_REMOVE_REDUNDANCY', 0.01)) + +# Chimera graph +m = int(os.getenv('GRID_M', 5)) # grid size +n = int(os.getenv('GRID_N', 5)) # grid size +t = 4 # shore size + + +############################### Evolution ###################################### +# d = DrawEmbedding(m, n, t) + + +def different_params(): + # # --- Clear + # try: + # shutil.rmtree('./out/') + # except FileNotFoundError: + # pass + # os.mkdir('./out') + + prob_steps = int(os.getenv('PROB_STEPS', 20)) + for prob in np.linspace(0.0, 1.0, num=prob_steps): + prob = round(prob, 2) + print(f'Started probability {prob}') + graph_number = int(os.getenv('K_GRAPH', 8)) + graph = TestGraph.k(graph_number) + start_time = time.time() + start_multiprocessing((graph, prob), f'k{graph_number}prob{prob}') + duration = time.time() - start_time + print(f'Duration for probability {prob}: {duration} s') + + +def start_multiprocessing(plot_params, name: str): + processes = multiprocessing.cpu_count() * int(os.getenv('CORE_PERCENTAGE', 75)) // 100 + with multiprocessing.Pool(processes) as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, plot_params), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/howManyGenerations_{m}x{n}_{max_total}_{max_generations}gen_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(plot_params, j) -> int: + solver = EmbeddingSolver(plot_params[0], m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver, plot_params) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + # save_embedding(*solver.get_embedding(), d, f'{j}-{i}final', plot_params, + # title=f'Generation {i} (final with redundancy removed)') + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver, plot_params) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + evo_params = EvolutionParams( + population_size=int(os.getenv('POPSIZE', 6)), + max_mutation_trials=int(os.getenv('MAX_MUTATION_TRIALS', 30)), + mutation_extend_to_free_neighbors_probability=plot_params[1] + ) + + child = solver.generate_population_and_select(evo_params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + +# def save_embedding(nodes: set[int], edges: set[tuple[int, int, int]], +# mapping_G_to_H, d: DrawEmbedding, name: str, plot_params, title=''): +# logger.info('') +# logger.info('🎈 Current embedding') +# logger.info(f'edges: {edges}') +# logger.info(f'mapping_G_to_H: {mapping_G_to_H}') + +# d.draw_whole_embedding_step(nodes, edges, mapping_G_to_H, title=title) + +# folder_path = f'./out/popsize{plot_params[1]}' +# if not os.path.exists(folder_path): +# os.mkdir(folder_path) +# d.save_and_clear(os.path.join(folder_path, f'{name}.svg')) + + +if __name__ == "__main__": + different_params() diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.0.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.0.txt new file mode 100644 index 0000000..8b47c05 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.0.txt @@ -0,0 +1,20 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.02.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.02.txt new file mode 100644 index 0000000..8b47c05 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.02.txt @@ -0,0 +1,20 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.04.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.04.txt new file mode 100644 index 0000000..6ff6aa4 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.04.txt @@ -0,0 +1,20 @@ +-1 +-1 +33 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.07.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.07.txt new file mode 100644 index 0000000..167a3e3 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.07.txt @@ -0,0 +1,20 @@ +30 +37 +-1 +-1 +66 +-1 +-1 +-1 +104 +-1 +40 +46 +-1 +139 +48 +58 +91 +185 +350 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.09.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.09.txt new file mode 100644 index 0000000..7263e13 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.09.txt @@ -0,0 +1,20 @@ +18 +39 +57 +60 +87 +69 +28 +86 +-1 +-1 +103 +109 +30 +-1 +-1 +105 +109 +159 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.11.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.11.txt new file mode 100644 index 0000000..d4d2107 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.11.txt @@ -0,0 +1,20 @@ +-1 +37 +36 +70 +31 +19 +169 +46 +30 +73 +68 +125 +-1 +176 +42 +175 +55 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.13.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.13.txt new file mode 100644 index 0000000..6c0af99 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.13.txt @@ -0,0 +1,20 @@ +24 +36 +58 +87 +110 +80 +110 +29 +27 +145 +94 +19 +42 +74 +86 +96 +127 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.16.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.16.txt new file mode 100644 index 0000000..dcce408 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.16.txt @@ -0,0 +1,20 @@ +32 +52 +93 +20 +24 +135 +194 +71 +60 +212 +128 +109 +432 +197 +28 +123 +301 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.18.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.18.txt new file mode 100644 index 0000000..aba09a8 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.18.txt @@ -0,0 +1,20 @@ +76 +139 +15 +150 +82 +23 +125 +226 +116 +246 +76 +80 +135 +110 +64 +58 +412 +214 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.2.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.2.txt new file mode 100644 index 0000000..6ca6f3e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.2.txt @@ -0,0 +1,20 @@ +30 +68 +66 +152 +110 +127 +46 +46 +235 +91 +93 +48 +90 +159 +124 +435 +118 +-1 +356 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.22.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.22.txt new file mode 100644 index 0000000..8976bfb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.22.txt @@ -0,0 +1,20 @@ +16 +55 +61 +56 +21 +172 +211 +74 +271 +108 +141 +396 +35 +79 +149 +224 +353 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.24.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.24.txt new file mode 100644 index 0000000..e88b8bf --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.24.txt @@ -0,0 +1,20 @@ +16 +39 +30 +42 +17 +46 +74 +83 +63 +43 +54 +56 +96 +84 +103 +85 +52 +110 +194 +336 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.27.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.27.txt new file mode 100644 index 0000000..4689367 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.27.txt @@ -0,0 +1,20 @@ +37 +56 +80 +172 +186 +103 +33 +63 +358 +117 +349 +19 +41 +53 +-1 +132 +395 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.29.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.29.txt new file mode 100644 index 0000000..2146e44 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.29.txt @@ -0,0 +1,20 @@ +16 +15 +26 +31 +40 +53 +23 +53 +113 +160 +33 +76 +157 +176 +129 +106 +232 +402 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.31.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.31.txt new file mode 100644 index 0000000..1fcebcc --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.31.txt @@ -0,0 +1,20 @@ +73 +63 +34 +114 +41 +121 +128 +44 +45 +181 +66 +21 +76 +67 +44 +147 +132 +286 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.33.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.33.txt new file mode 100644 index 0000000..065ef77 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.33.txt @@ -0,0 +1,20 @@ +17 +65 +107 +139 +119 +37 +135 +49 +230 +149 +175 +363 +390 +120 +72 +29 +-1 +-1 +501 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.36.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.36.txt new file mode 100644 index 0000000..e98a491 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.36.txt @@ -0,0 +1,20 @@ +41 +64 +158 +106 +216 +44 +20 +249 +241 +14 +209 +132 +59 +96 +102 +-1 +-1 +493 +389 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.38.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.38.txt new file mode 100644 index 0000000..23942fa --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.38.txt @@ -0,0 +1,20 @@ +22 +58 +99 +99 +76 +109 +20 +178 +34 +16 +102 +107 +83 +91 +69 +381 +445 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.4.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.4.txt new file mode 100644 index 0000000..9e0dcc8 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob0.4.txt @@ -0,0 +1,20 @@ +45 +40 +55 +15 +80 +68 +53 +196 +277 +116 +194 +23 +15 +265 +84 +-1 +469 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.0.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.0.txt new file mode 100644 index 0000000..8b47c05 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.0.txt @@ -0,0 +1,20 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.11.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.11.txt new file mode 100644 index 0000000..439392f --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.11.txt @@ -0,0 +1,20 @@ +24 +46 +51 +25 +114 +134 +46 +59 +137 +78 +72 +137 +18 +67 +39 +-1 +92 +159 +143 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.22.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.22.txt new file mode 100644 index 0000000..9103731 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.22.txt @@ -0,0 +1,20 @@ +29 +45 +97 +99 +233 +85 +103 +333 +110 +429 +77 +-1 +51 +81 +-1 +560 +481 +218 +-1 +207 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.33.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.33.txt new file mode 100644 index 0000000..0a8d52e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.33.txt @@ -0,0 +1,20 @@ +38 +31 +52 +52 +83 +27 +41 +34 +164 +75 +14 +119 +66 +97 +168 +77 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.44.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.44.txt new file mode 100644 index 0000000..75b9942 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.44.txt @@ -0,0 +1,20 @@ +43 +112 +125 +143 +41 +38 +62 +65 +66 +222 +61 +30 +497 +57 +-1 +225 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.56.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.56.txt new file mode 100644 index 0000000..c935e2c --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.56.txt @@ -0,0 +1,20 @@ +108 +189 +250 +268 +367 +146 +240 +93 +97 +542 +23 +-1 +312 +-1 +443 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.67.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.67.txt new file mode 100644 index 0000000..d68d684 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.67.txt @@ -0,0 +1,20 @@ +42 +58 +33 +104 +146 +195 +251 +179 +184 +196 +49 +112 +224 +230 +251 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.78.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.78.txt new file mode 100644 index 0000000..a0b6480 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.78.txt @@ -0,0 +1,20 @@ +103 +140 +211 +198 +64 +211 +214 +151 +119 +402 +69 +71 +82 +37 +59 +-1 +199 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.89.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.89.txt new file mode 100644 index 0000000..57cf01e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob0.89.txt @@ -0,0 +1,20 @@ +27 +32 +27 +60 +75 +136 +137 +162 +177 +169 +69 +85 +428 +-1 +-1 +286 +-1 +-1 +577 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob1.0.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob1.0.txt new file mode 100644 index 0000000..6e20caf --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob1.0.txt @@ -0,0 +1,20 @@ +15 +46 +77 +120 +233 +194 +131 +260 +259 +14 +545 +-1 +93 +-1 +-1 +538 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob_times.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob_times.txt new file mode 100644 index 0000000..76da838 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k8prob_times.txt @@ -0,0 +1,10 @@ +1st file: "howManyGenerations_5x5_20_600gen_k8prob0.0.txt" + +0.0: 15.64s +0.11: 158.63s +0.22: 153.62s +0.33: 121.46s +0.44: 144.53s +0.56: 171.68s +0.67: 137.82s +0.78: 101.41s diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_1000_600gen_k8prob0.0.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_1000_600gen_k8prob0.0.txt new file mode 100644 index 0000000..033cb5b --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_1000_600gen_k8prob0.0.txt @@ -0,0 +1,1000 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.0.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.0.txt new file mode 100644 index 0000000..8cd991e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.0.txt @@ -0,0 +1,300 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.05.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.05.txt new file mode 100644 index 0000000..9be3151 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.05.txt @@ -0,0 +1,300 @@ +-1 +-1 +-1 +48 +-1 +-1 +-1 +-1 +59 +-1 +-1 +-1 +-1 +24 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +39 +-1 +30 +-1 +-1 +-1 +31 +-1 +28 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +28 +-1 +52 +-1 +-1 +-1 +249 +-1 +-1 +55 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +61 +-1 +113 +-1 +36 +-1 +-1 +-1 +-1 +33 +-1 +-1 +32 +20 +156 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +45 +-1 +-1 +-1 +-1 +21 +-1 +-1 +-1 +-1 +74 +26 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +41 +-1 +-1 +-1 +51 +-1 +-1 +-1 +-1 +29 +-1 +58 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +20 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +26 +-1 +-1 +-1 +34 +-1 +-1 +30 +-1 +-1 +33 +-1 +-1 +33 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +17 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +48 +85 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +27 +-1 +-1 +42 +24 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +31 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +43 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +50 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.11.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.11.txt new file mode 100644 index 0000000..d3fa1f9 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.11.txt @@ -0,0 +1,300 @@ +28 +35 +19 +32 +80 +-1 +42 +14 +148 +110 +47 +48 +-1 +67 +-1 +26 +75 +15 +393 +40 +70 +138 +469 +-1 +55 +-1 +322 +115 +229 +56 +108 +130 +25 +320 +81 +-1 +113 +81 +222 +84 +-1 +61 +-1 +135 +93 +119 +86 +202 +215 +31 +20 +114 +195 +115 +151 +47 +29 +-1 +242 +524 +18 +22 +24 +46 +106 +66 +-1 +-1 +-1 +66 +85 +82 +43 +36 +51 +121 +-1 +94 +41 +322 +-1 +71 +32 +21 +15 +47 +72 +-1 +58 +64 +218 +24 +28 +31 +43 +-1 +80 +203 +18 +48 +50 +15 +-1 +36 +22 +71 +69 +50 +-1 +271 +94 +90 +122 +71 +34 +40 +-1 +71 +598 +59 +42 +-1 +172 +357 +154 +-1 +-1 +-1 +258 +46 +47 +25 +45 +67 +96 +40 +118 +43 +16 +77 +39 +99 +31 +76 +-1 +101 +302 +216 +44 +75 +45 +96 +58 +295 +58 +17 +24 +128 +55 +-1 +56 +85 +213 +95 +82 +38 +66 +-1 +120 +93 +-1 +80 +215 +87 +-1 +-1 +81 +-1 +101 +376 +-1 +-1 +39 +74 +58 +-1 +-1 +69 +37 +64 +51 +59 +-1 +109 +129 +49 +135 +129 +72 +150 +-1 +45 +-1 +34 +123 +417 +-1 +75 +-1 +31 +-1 +-1 +100 +277 +123 +259 +95 +124 +92 +18 +-1 +58 +60 +40 +82 +-1 +42 +95 +55 +17 +74 +-1 +68 +185 +46 +110 +26 +-1 +-1 +78 +-1 +165 +129 +92 +205 +52 +29 +67 +88 +-1 +169 +62 +-1 +-1 +94 +191 +319 +196 +-1 +66 +57 +-1 +93 +-1 +49 +-1 +73 +18 +24 +179 +46 +91 +-1 +157 +33 +-1 +15 +40 +49 +261 +68 +-1 +-1 +42 +33 +-1 +36 +129 +102 +56 +296 +24 +22 +50 +34 +14 +44 +35 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.16.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.16.txt new file mode 100644 index 0000000..8c5bf51 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.16.txt @@ -0,0 +1,300 @@ +244 +47 +407 +31 +111 +47 +-1 +43 +-1 +-1 +-1 +113 +111 +66 +84 +215 +141 +-1 +129 +107 +57 +50 +194 +271 +185 +68 +77 +227 +65 +73 +80 +-1 +82 +123 +47 +72 +37 +131 +87 +-1 +493 +429 +-1 +-1 +560 +-1 +134 +75 +170 +41 +99 +21 +112 +18 +33 +149 +41 +52 +143 +18 +100 +-1 +292 +49 +341 +36 +87 +-1 +109 +-1 +247 +46 +17 +41 +68 +53 +322 +18 +160 +191 +34 +131 +138 +87 +24 +17 +314 +71 +231 +26 +42 +19 +104 +-1 +31 +142 +72 +109 +84 +35 +47 +286 +-1 +253 +143 +269 +368 +55 +20 +82 +20 +24 +-1 +111 +-1 +152 +214 +60 +89 +22 +194 +157 +78 +577 +121 +14 +231 +26 +-1 +-1 +55 +90 +73 +67 +99 +67 +43 +198 +67 +21 +233 +29 +18 +82 +35 +61 +56 +117 +40 +15 +27 +84 +68 +-1 +105 +55 +53 +175 +-1 +194 +131 +35 +102 +159 +-1 +309 +61 +195 +74 +35 +14 +39 +397 +100 +539 +170 +252 +81 +184 +91 +223 +-1 +22 +43 +122 +-1 +20 +51 +102 +62 +129 +503 +219 +141 +-1 +272 +56 +-1 +91 +16 +81 +232 +444 +173 +116 +245 +-1 +-1 +64 +307 +59 +39 +28 +-1 +152 +234 +94 +142 +66 +22 +174 +317 +-1 +45 +477 +80 +-1 +138 +447 +-1 +530 +-1 +18 +-1 +-1 +183 +-1 +170 +69 +60 +61 +31 +148 +135 +56 +98 +-1 +38 +19 +122 +60 +215 +96 +57 +-1 +179 +107 +158 +45 +109 +157 +189 +37 +36 +207 +71 +143 +48 +77 +35 +67 +254 +-1 +14 +402 +141 +450 +149 +-1 +66 +40 +273 +68 +270 +160 +123 +97 +15 +48 +56 +183 +274 +177 +251 +-1 +58 +122 +96 +156 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.21.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.21.txt new file mode 100644 index 0000000..9a9f163 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.21.txt @@ -0,0 +1,300 @@ +27 +63 +31 +93 +130 +147 +328 +32 +208 +-1 +-1 +46 +107 +286 +51 +69 +157 +186 +40 +153 +153 +96 +31 +14 +66 +45 +-1 +-1 +571 +20 +301 +-1 +413 +-1 +132 +116 +141 +16 +16 +42 +62 +58 +35 +34 +79 +21 +-1 +-1 +143 +94 +-1 +175 +23 +37 +-1 +-1 +156 +-1 +174 +236 +137 +54 +24 +14 +-1 +-1 +88 +203 +64 +113 +97 +60 +281 +-1 +83 +69 +-1 +-1 +-1 +-1 +50 +118 +87 +513 +29 +-1 +212 +170 +90 +412 +35 +86 +21 +-1 +-1 +58 +60 +15 +94 +32 +166 +381 +90 +-1 +22 +135 +354 +192 +-1 +29 +131 +68 +70 +-1 +39 +566 +-1 +-1 +14 +178 +191 +-1 +134 +17 +34 +-1 +-1 +47 +220 +81 +60 +96 +104 +-1 +92 +163 +-1 +49 +21 +343 +-1 +63 +460 +18 +112 +92 +198 +44 +280 +58 +231 +83 +102 +26 +23 +93 +68 +40 +-1 +33 +-1 +-1 +136 +108 +17 +56 +43 +16 +238 +41 +101 +117 +-1 +-1 +-1 +33 +59 +23 +44 +98 +90 +93 +14 +59 +-1 +23 +136 +47 +41 +261 +56 +123 +71 +135 +17 +54 +41 +-1 +61 +101 +278 +162 +195 +223 +33 +28 +58 +89 +114 +44 +93 +145 +168 +35 +46 +246 +37 +55 +-1 +40 +32 +259 +135 +87 +150 +46 +85 +96 +-1 +-1 +116 +183 +17 +209 +428 +-1 +16 +-1 +237 +83 +83 +176 +95 +233 +115 +153 +189 +122 +166 +21 +31 +296 +-1 +28 +49 +233 +56 +104 +32 +29 +33 +16 +273 +318 +122 +204 +97 +65 +33 +140 +-1 +168 +20 +168 +58 +50 +14 +94 +156 +24 +396 +158 +568 +-1 +-1 +32 +90 +56 +16 +-1 +67 +64 +66 +-1 +-1 +72 +-1 +89 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.26.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.26.txt new file mode 100644 index 0000000..4f1d00d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.26.txt @@ -0,0 +1,300 @@ +18 +104 +163 +64 +85 +-1 +-1 +195 +21 +284 +21 +-1 +363 +70 +104 +-1 +358 +50 +-1 +179 +47 +72 +113 +42 +163 +153 +-1 +111 +129 +38 +-1 +180 +-1 +51 +46 +84 +32 +111 +508 +244 +59 +35 +45 +195 +229 +70 +217 +-1 +40 +170 +64 +254 +370 +142 +-1 +33 +312 +64 +98 +44 +52 +134 +42 +485 +42 +171 +103 +115 +125 +74 +301 +50 +-1 +168 +31 +49 +199 +-1 +41 +73 +95 +41 +136 +106 +-1 +175 +245 +23 +17 +145 +-1 +-1 +120 +122 +47 +235 +-1 +-1 +71 +61 +252 +104 +78 +-1 +312 +163 +-1 +22 +90 +17 +192 +187 +27 +574 +85 +-1 +356 +101 +231 +208 +424 +346 +166 +46 +120 +44 +454 +15 +278 +301 +43 +519 +201 +112 +83 +16 +85 +14 +95 +138 +22 +-1 +117 +22 +115 +91 +138 +174 +39 +42 +-1 +242 +-1 +39 +64 +-1 +73 +-1 +-1 +400 +-1 +45 +131 +68 +209 +40 +188 +449 +106 +36 +62 +89 +-1 +62 +49 +-1 +47 +138 +55 +73 +-1 +37 +301 +113 +75 +-1 +102 +-1 +199 +114 +103 +26 +15 +92 +75 +214 +107 +47 +167 +32 +65 +129 +87 +217 +26 +-1 +194 +65 +38 +-1 +40 +107 +201 +92 +130 +21 +50 +-1 +335 +218 +31 +219 +-1 +69 +-1 +33 +-1 +54 +58 +159 +-1 +47 +92 +42 +-1 +56 +-1 +391 +-1 +40 +14 +15 +63 +231 +228 +-1 +164 +-1 +86 +62 +218 +-1 +-1 +61 +51 +16 +252 +48 +491 +-1 +76 +73 +113 +530 +135 +218 +233 +315 +-1 +-1 +377 +23 +29 +26 +-1 +160 +-1 +15 +72 +18 +-1 +21 +559 +63 +34 +68 +-1 +-1 +32 +163 +100 +164 +67 +39 +77 +196 +304 +147 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.32.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.32.txt new file mode 100644 index 0000000..3cb523d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.32.txt @@ -0,0 +1,300 @@ +113 +60 +345 +-1 +-1 +73 +87 +133 +46 +108 +50 +-1 +53 +67 +22 +37 +76 +15 +102 +44 +157 +63 +546 +-1 +44 +16 +16 +21 +192 +165 +-1 +80 +220 +-1 +166 +63 +65 +71 +193 +145 +115 +53 +304 +338 +214 +204 +203 +265 +175 +184 +-1 +183 +-1 +398 +85 +-1 +209 +390 +-1 +270 +-1 +73 +35 +-1 +-1 +26 +-1 +68 +151 +115 +57 +395 +-1 +246 +87 +491 +138 +-1 +357 +104 +182 +248 +15 +335 +41 +22 +-1 +232 +303 +30 +24 +202 +201 +20 +67 +69 +42 +105 +90 +60 +76 +68 +63 +253 +-1 +45 +53 +24 +193 +73 +351 +159 +52 +15 +69 +94 +-1 +467 +37 +30 +218 +213 +28 +-1 +23 +393 +71 +141 +431 +37 +223 +56 +115 +300 +-1 +30 +21 +-1 +41 +52 +233 +168 +25 +246 +80 +54 +-1 +-1 +32 +228 +25 +36 +120 +178 +517 +26 +-1 +15 +101 +176 +-1 +25 +50 +164 +-1 +74 +57 +59 +-1 +61 +256 +16 +122 +404 +142 +-1 +35 +-1 +99 +186 +-1 +54 +58 +117 +-1 +59 +322 +190 +-1 +121 +233 +90 +178 +56 +139 +-1 +19 +221 +111 +-1 +434 +34 +200 +198 +249 +68 +-1 +52 +-1 +183 +111 +-1 +86 +170 +113 +24 +265 +174 +120 +293 +202 +129 +186 +-1 +16 +51 +-1 +246 +219 +528 +356 +531 +69 +505 +109 +59 +31 +67 +32 +410 +25 +20 +-1 +48 +217 +41 +102 +16 +37 +318 +159 +94 +179 +52 +74 +-1 +483 +14 +253 +-1 +150 +69 +35 +48 +-1 +-1 +28 +52 +292 +64 +386 +71 +72 +159 +123 +291 +77 +-1 +290 +72 +65 +37 +16 +36 +22 +40 +-1 +229 +272 +67 +318 +194 +529 +24 +178 +170 +98 +53 +71 +154 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.37.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.37.txt new file mode 100644 index 0000000..1c55408 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.37.txt @@ -0,0 +1,300 @@ +155 +199 +16 +312 +103 +275 +45 +126 +260 +-1 +82 +19 +102 +196 +45 +247 +59 +105 +20 +-1 +88 +14 +196 +21 +-1 +19 +-1 +69 +-1 +43 +138 +68 +80 +426 +-1 +-1 +-1 +379 +80 +67 +25 +62 +35 +-1 +112 +33 +225 +369 +-1 +123 +93 +224 +144 +-1 +179 +143 +467 +159 +365 +120 +169 +155 +-1 +137 +16 +-1 +28 +161 +-1 +59 +34 +355 +71 +64 +277 +34 +-1 +-1 +50 +73 +74 +42 +55 +45 +179 +30 +15 +-1 +344 +89 +200 +-1 +-1 +287 +-1 +39 +77 +360 +71 +20 +15 +17 +-1 +-1 +223 +52 +180 +14 +190 +-1 +-1 +229 +-1 +259 +48 +88 +18 +381 +87 +25 +83 +167 +-1 +-1 +256 +194 +-1 +102 +-1 +111 +109 +60 +127 +42 +-1 +199 +25 +16 +66 +-1 +148 +529 +33 +78 +363 +45 +40 +129 +92 +-1 +67 +39 +38 +99 +27 +275 +-1 +-1 +222 +196 +190 +527 +-1 +51 +63 +-1 +110 +374 +283 +207 +114 +206 +162 +150 +-1 +-1 +211 +-1 +273 +334 +-1 +33 +240 +95 +95 +45 +66 +55 +336 +-1 +108 +419 +173 +-1 +87 +246 +197 +132 +52 +217 +-1 +43 +233 +158 +203 +-1 +129 +49 +341 +45 +150 +75 +188 +14 +50 +-1 +233 +110 +-1 +29 +55 +183 +217 +401 +77 +37 +70 +279 +79 +111 +14 +61 +51 +-1 +108 +57 +56 +-1 +192 +574 +111 +53 +25 +39 +-1 +-1 +190 +187 +43 +230 +-1 +152 +133 +202 +53 +-1 +168 +32 +152 +135 +34 +39 +214 +-1 +292 +153 +15 +59 +15 +223 +-1 +505 +32 +20 +17 +58 +51 +70 +496 +291 +323 +122 +67 +188 +481 +-1 +60 +203 +173 +282 +20 +21 +199 +-1 +-1 +103 +82 +-1 +109 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.42.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.42.txt new file mode 100644 index 0000000..69fd650 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.42.txt @@ -0,0 +1,300 @@ +14 +64 +93 +20 +188 +252 +293 +403 +43 +47 +26 +386 +74 +129 +54 +130 +194 +78 +-1 +141 +221 +97 +494 +15 +170 +47 +29 +35 +73 +-1 +84 +188 +45 +186 +16 +99 +-1 +182 +130 +62 +-1 +172 +-1 +22 +-1 +109 +139 +94 +295 +68 +161 +36 +98 +-1 +123 +42 +32 +38 +-1 +72 +69 +229 +-1 +356 +-1 +-1 +243 +44 +30 +-1 +-1 +343 +103 +-1 +54 +101 +-1 +118 +77 +-1 +193 +56 +-1 +164 +-1 +349 +-1 +173 +174 +29 +588 +218 +264 +36 +264 +144 +322 +17 +-1 +15 +108 +44 +84 +541 +173 +108 +-1 +141 +499 +205 +37 +292 +230 +150 +432 +227 +-1 +53 +16 +-1 +215 +14 +53 +315 +-1 +93 +437 +55 +167 +177 +41 +182 +286 +16 +260 +148 +67 +29 +67 +182 +44 +92 +-1 +92 +212 +-1 +339 +67 +-1 +55 +42 +89 +66 +-1 +66 +282 +-1 +208 +56 +33 +28 +-1 +35 +-1 +196 +498 +62 +61 +69 +23 +44 +43 +-1 +406 +130 +81 +-1 +61 +314 +41 +186 +231 +-1 +104 +-1 +26 +139 +45 +42 +193 +27 +122 +552 +-1 +111 +333 +318 +37 +288 +-1 +57 +22 +45 +185 +377 +44 +153 +76 +134 +48 +30 +135 +67 +117 +47 +42 +167 +216 +147 +-1 +35 +-1 +110 +37 +207 +38 +89 +38 +-1 +140 +200 +-1 +39 +17 +20 +15 +138 +26 +435 +-1 +77 +70 +69 +43 +67 +193 +49 +123 +208 +72 +106 +199 +-1 +65 +156 +39 +156 +50 +93 +44 +-1 +298 +214 +360 +-1 +217 +90 +99 +315 +-1 +343 +545 +-1 +151 +31 +-1 +71 +253 +-1 +31 +50 +89 +95 +56 +76 +129 +104 +454 +70 +-1 +21 +124 +-1 +31 +200 +334 +333 +-1 +296 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.47.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.47.txt new file mode 100644 index 0000000..72e569f --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.47.txt @@ -0,0 +1,300 @@ +108 +245 +260 +243 +86 +232 +51 +96 +263 +101 +-1 +163 +18 +248 +57 +53 +44 +380 +216 +153 +311 +210 +60 +-1 +77 +101 +537 +197 +-1 +56 +85 +154 +132 +-1 +437 +127 +263 +-1 +183 +131 +66 +117 +91 +87 +244 +186 +324 +97 +-1 +39 +-1 +-1 +-1 +129 +413 +108 +373 +89 +181 +68 +-1 +51 +173 +208 +44 +140 +95 +222 +45 +-1 +-1 +157 +45 +-1 +16 +-1 +44 +132 +26 +95 +87 +147 +179 +129 +23 +-1 +65 +78 +384 +-1 +123 +28 +-1 +190 +357 +52 +-1 +-1 +30 +149 +-1 +196 +-1 +197 +241 +-1 +107 +71 +170 +477 +-1 +82 +42 +149 +80 +407 +-1 +-1 +434 +76 +208 +156 +66 +297 +29 +-1 +230 +342 +139 +113 +379 +448 +191 +364 +34 +553 +60 +45 +60 +123 +-1 +14 +190 +-1 +-1 +-1 +308 +177 +222 +95 +116 +350 +-1 +-1 +-1 +-1 +-1 +98 +89 +-1 +59 +197 +53 +116 +41 +-1 +117 +-1 +15 +46 +-1 +-1 +149 +-1 +-1 +-1 +136 +143 +138 +-1 +-1 +61 +80 +-1 +66 +80 +89 +52 +48 +37 +442 +83 +184 +123 +145 +27 +204 +521 +338 +395 +63 +91 +210 +168 +29 +209 +-1 +197 +71 +-1 +-1 +151 +155 +-1 +459 +52 +68 +347 +-1 +-1 +38 +22 +155 +206 +-1 +46 +103 +16 +-1 +83 +163 +117 +74 +-1 +-1 +374 +360 +245 +18 +-1 +122 +315 +53 +80 +564 +-1 +62 +324 +-1 +-1 +-1 +98 +-1 +178 +161 +15 +79 +156 +228 +27 +127 +-1 +118 +381 +296 +98 +22 +14 +-1 +21 +167 +195 +19 +214 +61 +568 +-1 +359 +38 +91 +27 +-1 +576 +58 +15 +490 +100 +67 +390 +213 +35 +-1 +53 +-1 +179 +111 +211 +208 +519 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.53.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.53.txt new file mode 100644 index 0000000..b3d37c0 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.53.txt @@ -0,0 +1,300 @@ +31 +43 +207 +104 +57 +437 +27 +99 +142 +-1 +63 +56 +114 +216 +92 +130 +43 +178 +-1 +25 +194 +187 +113 +-1 +48 +109 +155 +-1 +130 +314 +-1 +498 +-1 +190 +16 +128 +-1 +68 +311 +-1 +195 +69 +379 +17 +72 +37 +-1 +95 +312 +323 +154 +77 +64 +101 +101 +268 +137 +122 +192 +95 +146 +441 +76 +49 +-1 +25 +72 +506 +-1 +94 +53 +195 +107 +272 +-1 +162 +19 +68 +49 +80 +41 +189 +370 +49 +127 +84 +47 +41 +-1 +155 +227 +578 +-1 +51 +91 +48 +-1 +107 +279 +374 +504 +38 +201 +306 +42 +-1 +163 +58 +231 +-1 +-1 +-1 +185 +22 +58 +-1 +214 +20 +132 +40 +-1 +-1 +599 +93 +14 +203 +-1 +98 +-1 +-1 +22 +560 +187 +204 +78 +242 +-1 +37 +156 +-1 +45 +198 +43 +201 +-1 +221 +-1 +178 +20 +-1 +20 +48 +44 +50 +34 +77 +17 +-1 +99 +-1 +56 +179 +57 +83 +522 +-1 +416 +281 +49 +193 +101 +48 +14 +62 +64 +86 +192 +64 +71 +77 +84 +67 +274 +595 +136 +167 +451 +107 +139 +-1 +61 +122 +127 +-1 +49 +120 +-1 +91 +47 +-1 +-1 +322 +248 +232 +84 +125 +149 +393 +70 +121 +-1 +-1 +-1 +-1 +326 +21 +64 +321 +-1 +25 +51 +-1 +55 +72 +99 +-1 +196 +-1 +222 +55 +475 +220 +403 +37 +-1 +66 +-1 +44 +-1 +205 +111 +185 +205 +78 +38 +195 +-1 +423 +170 +-1 +424 +18 +110 +17 +30 +106 +248 +112 +51 +126 +259 +330 +178 +77 +113 +157 +79 +192 +193 +134 +118 +-1 +119 +-1 +-1 +439 +-1 +146 +115 +292 +491 +117 +151 +-1 +98 +51 +80 +310 +-1 +37 +73 +38 +162 +-1 +-1 +89 +14 +163 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.58.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.58.txt new file mode 100644 index 0000000..b7602d2 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.58.txt @@ -0,0 +1,300 @@ +104 +98 +27 +16 +135 +182 +-1 +171 +18 +-1 +204 +151 +192 +35 +-1 +43 +-1 +-1 +200 +106 +130 +157 +185 +89 +164 +-1 +95 +224 +16 +348 +117 +57 +192 +153 +227 +243 +25 +42 +77 +38 +22 +73 +266 +152 +137 +81 +34 +-1 +25 +124 +535 +-1 +95 +179 +64 +124 +122 +223 +-1 +-1 +162 +62 +18 +119 +-1 +76 +-1 +246 +63 +-1 +206 +152 +80 +61 +180 +48 +371 +94 +-1 +-1 +182 +341 +410 +239 +67 +115 +83 +85 +223 +269 +265 +75 +-1 +127 +-1 +-1 +82 +300 +51 +187 +135 +444 +49 +166 +60 +34 +-1 +61 +-1 +291 +73 +-1 +-1 +383 +-1 +-1 +20 +-1 +181 +154 +59 +62 +-1 +134 +231 +137 +174 +-1 +223 +446 +61 +14 +32 +77 +53 +129 +213 +113 +142 +284 +136 +55 +-1 +-1 +110 +120 +85 +137 +-1 +99 +139 +-1 +355 +40 +94 +-1 +121 +143 +32 +103 +23 +363 +-1 +352 +-1 +-1 +158 +39 +-1 +43 +43 +47 +163 +84 +86 +26 +196 +-1 +102 +106 +227 +50 +135 +59 +153 +305 +-1 +151 +-1 +46 +66 +239 +-1 +15 +16 +190 +176 +207 +31 +-1 +358 +28 +75 +60 +16 +84 +258 +91 +43 +-1 +118 +67 +54 +489 +375 +191 +192 +231 +431 +51 +-1 +-1 +220 +55 +-1 +67 +40 +59 +276 +135 +-1 +210 +208 +62 +276 +310 +51 +14 +-1 +82 +140 +81 +83 +109 +64 +90 +306 +-1 +208 +35 +27 +-1 +41 +40 +50 +196 +-1 +169 +153 +15 +-1 +149 +63 +-1 +91 +502 +71 +18 +76 +155 +-1 +86 +120 +95 +65 +56 +222 +-1 +71 +433 +53 +120 +179 +29 +357 +127 +62 +583 +-1 +-1 +223 +65 +426 +48 +203 +80 +96 +106 +-1 +390 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.63.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.63.txt new file mode 100644 index 0000000..74795a4 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.63.txt @@ -0,0 +1,300 @@ +150 +141 +428 +107 +110 +-1 +-1 +53 +94 +55 +144 +284 +104 +68 +268 +201 +260 +68 +-1 +-1 +34 +160 +137 +112 +220 +132 +195 +75 +88 +260 +24 +56 +29 +-1 +49 +519 +66 +-1 +123 +61 +230 +92 +424 +95 +189 +298 +-1 +212 +83 +290 +76 +188 +351 +142 +163 +101 +208 +88 +17 +-1 +34 +225 +-1 +101 +76 +201 +121 +36 +-1 +79 +60 +187 +34 +36 +279 +61 +59 +142 +162 +263 +-1 +177 +-1 +-1 +31 +160 +207 +513 +16 +93 +16 +68 +82 +41 +150 +-1 +-1 +310 +176 +147 +-1 +227 +197 +200 +14 +193 +22 +-1 +133 +145 +92 +-1 +-1 +89 +183 +60 +19 +-1 +-1 +-1 +184 +-1 +-1 +80 +99 +292 +144 +41 +157 +103 +-1 +23 +-1 +-1 +119 +74 +58 +61 +-1 +75 +189 +-1 +207 +-1 +88 +75 +-1 +110 +95 +209 +483 +-1 +283 +47 +138 +-1 +235 +16 +222 +71 +54 +226 +-1 +443 +49 +167 +100 +-1 +166 +211 +430 +83 +241 +-1 +131 +271 +279 +480 +183 +-1 +-1 +-1 +211 +31 +178 +228 +60 +149 +310 +168 +232 +-1 +156 +190 +-1 +271 +-1 +-1 +220 +-1 +343 +233 +218 +81 +-1 +-1 +189 +-1 +-1 +-1 +113 +113 +19 +44 +47 +-1 +73 +194 +-1 +33 +75 +409 +31 +39 +139 +99 +56 +198 +72 +392 +120 +-1 +205 +51 +138 +-1 +213 +220 +96 +24 +63 +61 +-1 +-1 +149 +103 +72 +143 +204 +187 +378 +20 +63 +-1 +81 +117 +127 +327 +323 +43 +105 +-1 +45 +380 +79 +130 +45 +191 +284 +122 +-1 +64 +43 +54 +50 +149 +257 +187 +-1 +317 +340 +357 +135 +-1 +142 +74 +143 +27 +80 +-1 +37 +273 +54 +148 +111 +58 +102 +131 +490 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.68.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.68.txt new file mode 100644 index 0000000..5394445 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.68.txt @@ -0,0 +1,300 @@ +113 +94 +114 +470 +205 +73 +39 +165 +-1 +592 +-1 +-1 +14 +300 +460 +-1 +-1 +78 +69 +101 +-1 +48 +89 +-1 +152 +93 +198 +298 +214 +-1 +-1 +116 +31 +181 +129 +50 +186 +55 +229 +-1 +38 +121 +-1 +128 +34 +444 +33 +267 +23 +59 +175 +42 +225 +-1 +91 +138 +137 +22 +28 +188 +37 +145 +93 +-1 +16 +150 +451 +162 +96 +165 +-1 +198 +57 +275 +31 +143 +241 +200 +106 +80 +106 +192 +45 +336 +58 +-1 +87 +43 +45 +332 +202 +66 +118 +247 +47 +23 +94 +95 +85 +56 +170 +113 +103 +41 +77 +242 +-1 +401 +238 +131 +244 +35 +53 +-1 +79 +29 +-1 +48 +56 +49 +-1 +89 +-1 +279 +44 +-1 +-1 +21 +16 +70 +33 +17 +-1 +162 +-1 +46 +-1 +-1 +81 +202 +222 +-1 +348 +69 +75 +28 +-1 +176 +431 +-1 +-1 +439 +87 +142 +-1 +52 +194 +149 +17 +89 +105 +42 +213 +108 +110 +34 +68 +55 +-1 +68 +75 +422 +204 +-1 +90 +-1 +143 +548 +89 +73 +124 +41 +128 +-1 +56 +130 +96 +108 +460 +34 +193 +-1 +-1 +100 +-1 +24 +266 +303 +-1 +-1 +-1 +-1 +116 +74 +381 +-1 +65 +94 +-1 +150 +111 +112 +106 +76 +154 +-1 +-1 +152 +83 +56 +37 +198 +-1 +48 +390 +60 +196 +484 +323 +-1 +14 +77 +69 +94 +-1 +-1 +45 +159 +47 +124 +-1 +83 +-1 +64 +64 +37 +30 +-1 +45 +-1 +-1 +56 +-1 +57 +193 +514 +168 +38 +224 +106 +-1 +251 +14 +90 +261 +-1 +-1 +274 +-1 +593 +183 +-1 +219 +19 +137 +56 +-1 +157 +121 +39 +-1 +196 +223 +367 +62 +129 +-1 +-1 +-1 +40 +138 +-1 +392 +113 +65 +161 +462 +217 +453 +162 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.74.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.74.txt new file mode 100644 index 0000000..05a1864 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.74.txt @@ -0,0 +1,300 @@ +135 +31 +190 +50 +38 +-1 +433 +122 +61 +162 +-1 +112 +265 +15 +-1 +44 +-1 +-1 +417 +-1 +44 +368 +76 +93 +435 +479 +172 +141 +386 +39 +-1 +-1 +-1 +-1 +123 +122 +63 +211 +-1 +-1 +-1 +-1 +165 +193 +-1 +84 +124 +74 +217 +-1 +37 +170 +216 +195 +-1 +75 +26 +165 +159 +-1 +-1 +389 +75 +93 +299 +118 +-1 +-1 +147 +139 +-1 +54 +-1 +-1 +251 +185 +-1 +230 +128 +311 +241 +110 +293 +175 +73 +38 +152 +46 +277 +90 +45 +114 +-1 +67 +75 +107 +-1 +39 +120 +63 +-1 +14 +-1 +173 +-1 +403 +228 +-1 +366 +37 +70 +92 +33 +86 +26 +365 +-1 +251 +272 +27 +32 +75 +70 +25 +347 +-1 +381 +-1 +98 +15 +90 +81 +203 +175 +277 +-1 +209 +69 +181 +294 +-1 +74 +178 +146 +171 +106 +348 +43 +41 +75 +-1 +45 +-1 +82 +89 +116 +53 +17 +139 +62 +372 +-1 +165 +297 +29 +70 +394 +56 +-1 +203 +62 +126 +-1 +111 +176 +-1 +63 +-1 +169 +-1 +50 +176 +14 +476 +148 +37 +257 +144 +97 +257 +-1 +-1 +218 +-1 +-1 +191 +149 +246 +16 +-1 +91 +-1 +20 +124 +44 +-1 +-1 +82 +116 +-1 +-1 +85 +22 +27 +177 +15 +-1 +161 +269 +177 +-1 +-1 +279 +129 +272 +-1 +36 +277 +135 +420 +166 +118 +225 +84 +133 +-1 +242 +368 +269 +69 +33 +-1 +362 +529 +340 +41 +73 +70 +-1 +52 +70 +66 +171 +229 +170 +53 +479 +56 +541 +200 +-1 +-1 +268 +124 +231 +-1 +188 +-1 +193 +45 +371 +69 +34 +-1 +-1 +-1 +115 +183 +114 +120 +72 +323 +41 +116 +68 +177 +101 +-1 +374 +111 +42 +256 +244 +58 +126 +216 +90 +-1 +230 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.79.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.79.txt new file mode 100644 index 0000000..4f17c05 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.79.txt @@ -0,0 +1,300 @@ +113 +187 +188 +314 +164 +129 +351 +61 +-1 +47 +79 +196 +180 +-1 +580 +265 +35 +-1 +187 +-1 +199 +153 +-1 +338 +76 +64 +130 +43 +-1 +46 +279 +102 +135 +-1 +95 +375 +125 +41 +55 +351 +91 +200 +-1 +183 +63 +136 +49 +368 +-1 +277 +153 +137 +94 +145 +55 +288 +49 +73 +-1 +47 +29 +-1 +-1 +150 +199 +178 +121 +121 +-1 +-1 +220 +-1 +-1 +115 +269 +43 +82 +-1 +141 +140 +-1 +142 +84 +249 +228 +189 +-1 +-1 +495 +255 +-1 +62 +129 +-1 +584 +155 +176 +203 +203 +84 +271 +-1 +88 +239 +114 +382 +278 +197 +-1 +-1 +115 +-1 +24 +115 +-1 +401 +202 +-1 +-1 +239 +23 +304 +-1 +85 +48 +56 +326 +63 +520 +55 +63 +67 +24 +44 +120 +85 +-1 +59 +74 +67 +227 +104 +85 +260 +194 +54 +121 +243 +214 +35 +203 +67 +-1 +66 +125 +250 +86 +586 +-1 +-1 +-1 +356 +-1 +382 +354 +155 +131 +14 +159 +35 +85 +187 +-1 +-1 +123 +526 +-1 +-1 +55 +218 +70 +208 +122 +531 +346 +310 +-1 +188 +226 +120 +-1 +-1 +71 +151 +115 +-1 +-1 +336 +588 +128 +65 +101 +-1 +54 +-1 +455 +135 +148 +266 +95 +330 +-1 +60 +56 +103 +-1 +65 +278 +-1 +31 +34 +-1 +86 +250 +-1 +179 +-1 +-1 +-1 +72 +-1 +-1 +46 +254 +-1 +324 +91 +25 +67 +115 +451 +51 +22 +79 +19 +-1 +225 +25 +32 +16 +25 +-1 +58 +198 +-1 +162 +197 +161 +18 +266 +269 +250 +22 +64 +366 +118 +-1 +59 +154 +-1 +337 +407 +129 +53 +76 +-1 +211 +-1 +138 +150 +63 +413 +277 +58 +-1 +15 +38 +15 +110 +242 +118 +-1 +28 +190 +229 +272 +-1 +26 +115 +439 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.84.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.84.txt new file mode 100644 index 0000000..2cdf51d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.84.txt @@ -0,0 +1,300 @@ +87 +99 +178 +241 +397 +49 +-1 +339 +58 +206 +126 +35 +102 +278 +124 +43 +94 +182 +14 +201 +-1 +69 +246 +298 +98 +72 +554 +78 +-1 +338 +108 +-1 +269 +253 +80 +186 +350 +49 +181 +-1 +49 +101 +360 +-1 +124 +-1 +202 +57 +-1 +254 +400 +248 +-1 +137 +-1 +14 +61 +168 +-1 +187 +-1 +-1 +78 +-1 +63 +66 +-1 +145 +93 +21 +396 +51 +192 +146 +154 +349 +45 +15 +-1 +63 +123 +325 +78 +-1 +162 +35 +36 +365 +59 +460 +60 +122 +49 +45 +392 +284 +482 +-1 +106 +-1 +-1 +193 +33 +-1 +57 +285 +48 +78 +498 +287 +-1 +165 +14 +46 +-1 +133 +69 +218 +62 +310 +51 +-1 +234 +75 +-1 +116 +114 +-1 +-1 +113 +-1 +101 +-1 +92 +97 +139 +-1 +37 +14 +50 +156 +127 +66 +95 +61 +169 +24 +42 +36 +120 +-1 +586 +223 +-1 +14 +56 +233 +49 +552 +73 +183 +-1 +77 +25 +202 +-1 +64 +-1 +175 +314 +-1 +50 +-1 +-1 +250 +15 +-1 +96 +37 +128 +158 +493 +75 +75 +442 +40 +-1 +235 +445 +358 +137 +79 +478 +115 +592 +80 +64 +41 +118 +131 +34 +-1 +-1 +257 +84 +84 +16 +146 +52 +447 +179 +71 +137 +-1 +71 +38 +76 +132 +155 +-1 +43 +190 +196 +139 +54 +51 +53 +67 +449 +-1 +-1 +21 +175 +269 +116 +194 +156 +442 +100 +-1 +173 +28 +53 +195 +79 +88 +-1 +50 +116 +515 +127 +218 +530 +99 +-1 +-1 +72 +-1 +-1 +583 +441 +-1 +-1 +-1 +58 +77 +48 +-1 +186 +53 +-1 +57 +305 +102 +65 +146 +517 +-1 +20 +-1 +295 +-1 +296 +18 +171 +473 +26 +73 +383 +-1 +231 +169 +68 +258 +15 +55 +184 +57 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.89.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.89.txt new file mode 100644 index 0000000..1cda42d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.89.txt @@ -0,0 +1,300 @@ +150 +-1 +-1 +-1 +123 +355 +147 +67 +363 +319 +-1 +259 +15 +-1 +63 +55 +213 +70 +81 +53 +45 +25 +177 +103 +478 +281 +291 +326 +-1 +423 +464 +439 +49 +157 +19 +-1 +51 +418 +56 +31 +266 +217 +200 +-1 +48 +553 +127 +14 +23 +214 +40 +52 +34 +202 +-1 +136 +85 +90 +211 +102 +-1 +-1 +406 +143 +386 +131 +-1 +328 +311 +69 +34 +234 +-1 +146 +-1 +117 +-1 +231 +122 +185 +-1 +110 +54 +265 +244 +-1 +137 +81 +456 +236 +413 +77 +69 +171 +170 +-1 +387 +-1 +246 +-1 +-1 +85 +41 +-1 +-1 +413 +157 +-1 +-1 +154 +42 +260 +-1 +243 +16 +211 +-1 +141 +-1 +315 +58 +67 +253 +221 +97 +340 +326 +63 +121 +412 +288 +-1 +67 +83 +212 +392 +57 +-1 +566 +166 +123 +194 +15 +-1 +-1 +69 +-1 +250 +402 +138 +-1 +201 +116 +196 +265 +305 +204 +-1 +-1 +350 +-1 +241 +-1 +312 +407 +186 +88 +76 +136 +237 +330 +-1 +122 +71 +81 +129 +49 +92 +80 +-1 +41 +126 +-1 +148 +155 +-1 +53 +-1 +99 +130 +-1 +199 +320 +158 +134 +169 +47 +236 +-1 +36 +-1 +-1 +-1 +34 +107 +306 +425 +70 +450 +-1 +193 +41 +240 +499 +-1 +289 +279 +116 +281 +347 +262 +-1 +188 +73 +53 +45 +296 +208 +150 +-1 +98 +-1 +151 +-1 +364 +261 +358 +14 +186 +291 +104 +131 +-1 +-1 +94 +120 +22 +186 +32 +50 +152 +73 +132 +-1 +193 +87 +42 +192 +-1 +93 +-1 +65 +-1 +569 +68 +181 +94 +43 +-1 +101 +-1 +563 +171 +129 +118 +-1 +104 +-1 +365 +37 +265 +-1 +477 +-1 +293 +62 +400 +327 +64 +514 +-1 +59 +169 +87 +-1 +-1 +36 +247 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.95.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.95.txt new file mode 100644 index 0000000..8739c3d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob0.95.txt @@ -0,0 +1,300 @@ +78 +144 +247 +16 +131 +35 +-1 +-1 +228 +286 +-1 +219 +107 +126 +52 +111 +377 +203 +188 +61 +217 +306 +167 +208 +154 +324 +15 +338 +16 +-1 +-1 +-1 +-1 +-1 +471 +48 +440 +-1 +357 +76 +40 +159 +292 +542 +-1 +119 +97 +147 +35 +120 +115 +20 +-1 +130 +-1 +49 +66 +32 +211 +273 +115 +67 +-1 +-1 +176 +351 +332 +-1 +-1 +-1 +286 +174 +-1 +225 +-1 +168 +72 +38 +124 +-1 +125 +166 +-1 +-1 +73 +45 +-1 +-1 +276 +134 +316 +320 +37 +-1 +-1 +124 +53 +452 +417 +-1 +-1 +-1 +206 +-1 +231 +192 +327 +350 +-1 +526 +110 +-1 +76 +-1 +-1 +-1 +-1 +110 +159 +357 +269 +-1 +-1 +292 +62 +85 +557 +22 +-1 +-1 +355 +130 +57 +240 +63 +17 +114 +190 +257 +148 +103 +-1 +144 +108 +138 +-1 +487 +-1 +272 +175 +572 +48 +43 +15 +125 +49 +164 +171 +231 +91 +-1 +318 +171 +186 +137 +250 +364 +130 +113 +-1 +-1 +115 +314 +65 +534 +-1 +-1 +141 +14 +93 +201 +-1 +94 +29 +247 +-1 +235 +226 +426 +240 +141 +15 +223 +-1 +165 +77 +155 +391 +31 +246 +53 +199 +47 +543 +-1 +44 +114 +233 +208 +-1 +-1 +97 +186 +-1 +81 +216 +219 +251 +286 +134 +-1 +122 +-1 +459 +401 +14 +129 +556 +-1 +-1 +15 +-1 +-1 +346 +116 +128 +57 +152 +538 +380 +465 +118 +-1 +206 +-1 +209 +201 +400 +200 +50 +34 +483 +73 +-1 +97 +-1 +-1 +299 +82 +170 +-1 +245 +-1 +194 +44 +299 +207 +139 +-1 +446 +58 +15 +102 +165 +-1 +-1 +-1 +-1 +-1 +-1 +275 +562 +-1 +141 +-1 +207 +-1 +156 +-1 +163 +109 +139 +143 +-1 +-1 +223 +17 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob1.0.txt b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob1.0.txt new file mode 100644 index 0000000..96eb8fe --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob1.0.txt @@ -0,0 +1,300 @@ +61 +321 +440 +-1 +14 +-1 +99 +354 +452 +-1 +504 +32 +-1 +-1 +333 +-1 +-1 +-1 +-1 +84 +-1 +244 +77 +29 +-1 +28 +347 +212 +-1 +-1 +-1 +48 +97 +150 +-1 +-1 +-1 +-1 +164 +48 +184 +79 +251 +-1 +-1 +309 +-1 +95 +-1 +144 +-1 +201 +-1 +356 +-1 +172 +70 +440 +52 +-1 +381 +174 +36 +-1 +-1 +-1 +-1 +-1 +-1 +84 +544 +159 +-1 +189 +14 +-1 +330 +142 +539 +-1 +388 +-1 +-1 +463 +537 +92 +-1 +-1 +16 +174 +207 +-1 +-1 +291 +-1 +242 +134 +479 +15 +445 +488 +80 +290 +111 +14 +188 +110 +208 +165 +-1 +198 +195 +347 +-1 +434 +418 +-1 +126 +499 +373 +-1 +-1 +17 +-1 +353 +77 +-1 +-1 +-1 +-1 +-1 +334 +-1 +141 +-1 +190 +428 +264 +50 +180 +-1 +-1 +372 +70 +519 +-1 +-1 +93 +-1 +322 +-1 +14 +167 +-1 +-1 +101 +223 +-1 +393 +49 +-1 +574 +51 +-1 +75 +-1 +14 +119 +418 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +68 +156 +129 +-1 +417 +-1 +-1 +293 +-1 +-1 +575 +153 +-1 +21 +53 +-1 +280 +-1 +101 +511 +-1 +224 +-1 +-1 +-1 +55 +244 +-1 +476 +-1 +-1 +285 +-1 +-1 +-1 +-1 +198 +66 +-1 +16 +291 +-1 +-1 +314 +125 +-1 +253 +316 +286 +-1 +-1 +325 +406 +325 +-1 +-1 +375 +130 +139 +67 +-1 +-1 +323 +256 +220 +386 +103 +73 +14 +-1 +-1 +161 +457 +14 +170 +-1 +-1 +-1 +184 +255 +145 +67 +-1 +79 +-1 +-1 +215 +14 +338 +189 +-1 +-1 +15 +513 +-1 +48 +-1 +-1 +-1 +-1 +83 +-1 +175 +-1 +-1 +60 +-1 +183 +-1 +81 +-1 +102 +196 +-1 +60 +41 +-1 +-1 +127 +153 +284 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/docker-compose.yml b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/docker-compose.yml new file mode 100644 index 0000000..1bed37d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/docker-compose.yml @@ -0,0 +1,21 @@ +services: + major-miner: + build: . + container_name: major-miner + environment: + CORE_PERCENTAGE: 90 + MAX_MUTATION_TRIALS: 30 + PROB_EXTEND_TO_FREE_NEIGHBOR: 0.3 + MAX_TOTAL: 1000 + MAX_GENERATIONS: 600 + PROB_REMOVE_REDUNDANCY: 0.01 + GRID_M: 5 + GRID_N: 5 + POPSIZE: 6 + K_MIN: 1 + K_MAX: 40 + + volumes: + - type: bind + source: ./out + target: /app/out diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/evolution.py b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/evolution.py new file mode 100644 index 0000000..baa515c --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/evolution.py @@ -0,0 +1,117 @@ +# Move this file to src/solver to start +# This is a file used for docker with environment variables + +import logging +import multiprocessing +import os +import time +from functools import partial +from random import random +from typing import Optional + +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.graph.undirected_graph import UndirectedGraphAdjList +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + + +################################# Params ####################################### + +params = EvolutionParams( + population_size=int(os.getenv('POPSIZE', 6)), + max_mutation_trials=int(os.getenv('MAX_MUTATION_TRIALS', 30)), + mutation_extend_to_free_neighbors_probability=float( + os.getenv('PROB_EXTEND_TO_FREE_NEIGHBOR', 0.24)) # should be <=0.5 +) + +max_total = int(os.getenv('MAX_TOTAL', 100)) +max_generations = int(os.getenv('MAX_GENERATIONS', 600)) +remove_redundancy_probability = float(os.getenv('PROB_REMOVE_REDUNDANCY', 0.01)) + +# Chimera graph +m = int(os.getenv('GRID_M', 16)) # grid size +n = int(os.getenv('GRID_N', 16)) # grid size +t = 4 # shore size + + +############################### Evolution ###################################### + +def do_all_k_graphs(): + for i in range(int(os.getenv('K_MIN', 6)), int(os.getenv('K_MAX', 40)) + 1): + print(f'Started k{i}') + start_time = time.time() + start_multiprocessing(TestGraph.k(i), f'k{i}') + duration = time.time() - start_time + print(f'Duration for k{i}: {duration}') + + +def start_multiprocessing(H: UndirectedGraphAdjList, name: str): + processes = multiprocessing.cpu_count() * int(os.getenv('CORE_PERCENTAGE', 100)) // 100 + with multiprocessing.Pool(processes) as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, H), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/howManyGenerations_{m}x{n}_{max_total}_{max_generations}gen_{params.population_size}popsize_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(H: UndirectedGraphAdjList, i) -> int: + solver = EmbeddingSolver(H, m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + child = solver.generate_population_and_select(params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + + +if __name__ == "__main__": + do_all_k_graphs() diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k10.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k10.txt new file mode 100644 index 0000000..fb3128d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k10.txt @@ -0,0 +1,100 @@ +128 +223 +356 +175 +-1 +-1 +505 +-1 +120 +-1 +-1 +73 +528 +536 +-1 +263 +290 +244 +-1 +-1 +-1 +327 +425 +-1 +-1 +597 +-1 +-1 +-1 +-1 +-1 +-1 +459 +-1 +88 +-1 +-1 +-1 +-1 +221 +194 +213 +-1 +173 +-1 +-1 +159 +371 +-1 +-1 +-1 +179 +-1 +-1 +232 +-1 +-1 +-1 +-1 +505 +-1 +376 +-1 +-1 +-1 +255 +320 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +278 +-1 +425 +441 +-1 +173 +392 +-1 +381 +155 +349 +-1 +-1 +110 +-1 +75 +244 +234 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k11.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k11.txt new file mode 100644 index 0000000..c1f217a --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k11.txt @@ -0,0 +1,100 @@ +171 +307 +353 +-1 +-1 +-1 +-1 +-1 +207 +-1 +-1 +382 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +257 +359 +-1 +-1 +-1 +-1 +122 +-1 +409 +-1 +-1 +303 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +407 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +448 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +561 +587 +-1 +-1 +-1 +-1 +319 +362 +-1 +-1 +-1 +-1 +-1 +349 +-1 +-1 +-1 +-1 +-1 +296 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k12.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k12.txt new file mode 100644 index 0000000..d3cd83d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k12.txt @@ -0,0 +1,100 @@ +400 +-1 +578 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +489 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +371 +-1 +-1 +-1 +-1 +-1 +-1 +345 +-1 +-1 +-1 +-1 +-1 +479 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +172 +531 +-1 +297 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +484 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +499 +-1 +-1 +-1 +439 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k13.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k13.txt new file mode 100644 index 0000000..1b9e49d --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k13.txt @@ -0,0 +1,100 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +328 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +363 +-1 +-1 +-1 +-1 +-1 +-1 +340 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +529 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +536 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k6.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k6.txt new file mode 100644 index 0000000..f6c02a8 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k6.txt @@ -0,0 +1,100 @@ +8 +11 +21 +13 +11 +22 +27 +9 +29 +53 +19 +12 +10 +11 +18 +38 +18 +9 +24 +30 +30 +9 +40 +30 +69 +11 +19 +23 +15 +10 +18 +17 +14 +9 +7 +10 +28 +8 +20 +22 +29 +8 +30 +19 +11 +7 +24 +59 +29 +18 +14 +92 +11 +40 +7 +15 +53 +27 +13 +9 +19 +57 +77 +15 +13 +20 +37 +8 +14 +10 +20 +35 +44 +10 +26 +28 +9 +20 +20 +7 +27 +83 +84 +20 +12 +53 +10 +8 +26 +17 +14 +24 +29 +77 +210 +62 +103 +165 +142 +326 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k7.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k7.txt new file mode 100644 index 0000000..e8d9806 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k7.txt @@ -0,0 +1,100 @@ +14 +25 +20 +11 +33 +81 +30 +95 +187 +158 +116 +98 +17 +39 +24 +124 +61 +22 +15 +17 +22 +38 +44 +204 +342 +26 +299 +16 +222 +23 +28 +89 +274 +315 +14 +13 +14 +42 +-1 +107 +27 +-1 +86 +18 +186 +27 +34 +127 +19 +58 +50 +-1 +62 +-1 +40 +16 +-1 +100 +44 +47 +541 +-1 +72 +13 +11 +111 +95 +56 +50 +24 +20 +12 +37 +25 +-1 +42 +23 +28 +18 +55 +111 +18 +66 +24 +13 +19 +46 +51 +56 +156 +129 +15 +76 +80 +56 +73 +160 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k8.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k8.txt new file mode 100644 index 0000000..367af2c --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k8.txt @@ -0,0 +1,100 @@ +34 +115 +122 +217 +155 +41 +289 +23 +68 +357 +26 +74 +599 +-1 +34 +232 +41 +82 +-1 +177 +86 +326 +20 +43 +184 +-1 +-1 +327 +-1 +321 +505 +183 +45 +355 +-1 +68 +176 +480 +425 +59 +59 +-1 +32 +131 +58 +-1 +22 +-1 +21 +-1 +20 +199 +423 +408 +-1 +206 +23 +-1 +191 +16 +32 +-1 +-1 +34 +142 +104 +19 +-1 +-1 +234 +-1 +57 +-1 +316 +48 +-1 +-1 +-1 +477 +45 +267 +-1 +-1 +15 +-1 +61 +83 +87 +39 +59 +17 +215 +63 +47 +-1 +585 +92 +-1 +276 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k9.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k9.txt new file mode 100644 index 0000000..bc87122 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k9.txt @@ -0,0 +1,100 @@ +61 +66 +189 +254 +224 +69 +261 +61 +-1 +-1 +158 +-1 +-1 +312 +86 +110 +-1 +126 +188 +-1 +-1 +290 +69 +-1 +106 +128 +94 +-1 +180 +-1 +188 +82 +85 +-1 +-1 +246 +-1 +-1 +198 +-1 +-1 +36 +228 +31 +64 +-1 +54 +478 +373 +-1 +-1 +-1 +563 +-1 +78 +-1 +-1 +179 +-1 +475 +108 +-1 +-1 +305 +597 +263 +-1 +271 +373 +-1 +51 +173 +40 +-1 +73 +270 +368 +-1 +238 +-1 +-1 +590 +-1 +-1 +190 +-1 +-1 +152 +178 +205 +212 +-1 +-1 +-1 +289 +209 +323 +-1 +501 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_ktimes.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_ktimes.txt new file mode 100644 index 0000000..aed1cbb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_ktimes.txt @@ -0,0 +1,5 @@ +CPU: i7-6700 @ 3.40 GHz (around 3.6 GHz at execution) +4 cores, 60% used + +- previous data was lost (terminal closed too quickly) +- k13: 20154.59s \ No newline at end of file diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_k15.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_k15.txt new file mode 100644 index 0000000..b16a9fb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_k15.txt @@ -0,0 +1,100 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_k16.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_k16.txt new file mode 100644 index 0000000..b16a9fb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_k16.txt @@ -0,0 +1,100 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_ktimes.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_ktimes.txt new file mode 100644 index 0000000..2bcb5a6 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_100_600gen_6popsize_ktimes.txt @@ -0,0 +1,35 @@ +CPU: i5-8350U @ 1.70 GHz (around 2.5 GHz at execution) +4 cores, 100% used + +- K2: 3.04s +- K3: 5.25s +- K4: 8.83s +- K5: 16.20s +- K6: 20.99s +- K7: 109.49s +- K8: 239.84s +- K9: 197.11s +- K10: 98.86s +- K11: 64.00s +- K12: 53.02s +- K13: 42.98s +- K14: 58.70s +- K15: 61.46s +- K16: 48.78s +- K17 failed at 64/100 + + +second time (80% cpu and sharing with another process) +- K2: 4.77s +- K3: 8.05s +- K4: 13.13s +- K5: 17.48s +- K6: 29.51s +- K7: 108.64s +- K8: 351.69s +- K9: 221.80s +- K10: 107.57s +- K11: 72.60s +- K12: 70.01s +- K13: 58.08s +- K14: 59.24s \ No newline at end of file diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k10.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k10.txt new file mode 100644 index 0000000..122001e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k10.txt @@ -0,0 +1,200 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k11.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k11.txt new file mode 100644 index 0000000..122001e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k11.txt @@ -0,0 +1,200 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k12.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k12.txt new file mode 100644 index 0000000..122001e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k12.txt @@ -0,0 +1,200 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k13.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k13.txt new file mode 100644 index 0000000..122001e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k13.txt @@ -0,0 +1,200 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k14.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k14.txt new file mode 100644 index 0000000..122001e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k14.txt @@ -0,0 +1,200 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k2.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k2.txt new file mode 100644 index 0000000..c3aaa70 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k2.txt @@ -0,0 +1,200 @@ +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k3.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k3.txt new file mode 100644 index 0000000..56baa43 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k3.txt @@ -0,0 +1,200 @@ +1 +1 +1 +1 +1 +7 +1 +1 +1 +1 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +6 +1 +12 +1 +1 +1 +5 +1 +1 +3 +6 +1 +10 +1 +3 +1 +1 +1 +5 +1 +5 +1 +1 +1 +1 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +2 +1 +1 +1 +1 +1 +1 +1 +5 +4 +7 +1 +1 +4 +1 +1 +1 +5 +1 +4 +6 +1 +1 +3 +3 +7 +5 +1 +1 +1 +1 +1 +1 +7 +1 +1 +1 +1 +3 +1 +1 +3 +1 +3 +2 +1 +11 +5 +1 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +4 +4 +5 +1 +3 +7 +1 +1 +1 +1 +1 +4 +7 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +9 +1 +3 +1 +5 +6 +1 +1 +1 +3 +1 +1 +4 +1 +1 +2 +5 +1 +1 +1 +1 +1 +1 +1 +6 +1 +4 +4 +1 +4 +1 +1 +1 +1 +1 +6 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k4.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k4.txt new file mode 100644 index 0000000..1bfb943 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k4.txt @@ -0,0 +1,200 @@ +2 +1 +1 +1 +1 +1 +1 +2 +1 +2 +1 +1 +1 +1 +2 +1 +1 +11 +8 +1 +8 +2 +1 +1 +1 +2 +1 +1 +2 +1 +2 +9 +2 +1 +2 +8 +1 +2 +7 +7 +2 +9 +2 +1 +1 +1 +2 +2 +1 +8 +1 +15 +2 +2 +2 +1 +2 +1 +1 +3 +1 +9 +2 +3 +1 +1 +1 +9 +7 +6 +1 +2 +2 +2 +1 +1 +1 +11 +1 +1 +2 +1 +1 +2 +2 +1 +1 +2 +2 +1 +1 +1 +9 +1 +3 +3 +30 +14 +15 +11 +1 +2 +1 +2 +1 +1 +2 +14 +1 +10 +6 +3 +9 +13 +2 +1 +15 +1 +3 +2 +1 +2 +2 +2 +2 +7 +2 +1 +1 +3 +10 +6 +1 +2 +7 +6 +2 +8 +2 +1 +1 +1 +1 +3 +1 +1 +1 +2 +2 +2 +1 +2 +1 +2 +1 +10 +1 +1 +2 +1 +1 +1 +15 +8 +2 +2 +2 +3 +7 +1 +1 +7 +12 +1 +2 +7 +12 +1 +1 +3 +3 +6 +1 +1 +1 +1 +1 +8 +7 +1 +12 +2 +8 +7 +1 +3 +9 +8 +13 +11 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k5.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k5.txt new file mode 100644 index 0000000..87aca9e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k5.txt @@ -0,0 +1,200 @@ +2 +2 +2 +2 +10 +10 +2 +2 +16 +2 +2 +2 +2 +5 +6 +4 +3 +16 +2 +6 +2 +21 +3 +2 +37 +9 +3 +16 +18 +14 +2 +2 +20 +42 +18 +9 +7 +2 +2 +14 +35 +8 +2 +4 +2 +17 +2 +17 +2 +19 +35 +2 +7 +4 +32 +19 +9 +3 +4 +10 +11 +3 +20 +15 +2 +16 +2 +2 +11 +16 +32 +8 +2 +10 +6 +2 +15 +2 +20 +14 +38 +3 +2 +20 +2 +2 +4 +53 +2 +11 +23 +2 +2 +2 +5 +16 +17 +20 +28 +14 +2 +2 +2 +2 +2 +9 +16 +4 +2 +17 +3 +8 +16 +4 +19 +4 +2 +11 +2 +3 +2 +2 +4 +10 +7 +16 +10 +16 +9 +8 +2 +12 +7 +16 +2 +21 +13 +2 +15 +4 +4 +20 +11 +2 +5 +2 +7 +3 +13 +2 +17 +7 +58 +17 +42 +18 +20 +3 +2 +10 +3 +13 +6 +2 +15 +2 +11 +17 +2 +8 +3 +21 +14 +13 +8 +2 +2 +11 +3 +2 +2 +2 +18 +9 +19 +2 +30 +2 +14 +2 +9 +2 +13 +2 +20 +18 +3 +17 +20 +23 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k6.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k6.txt new file mode 100644 index 0000000..3bb0d8f --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k6.txt @@ -0,0 +1,200 @@ +7 +9 +8 +15 +18 +26 +23 +15 +21 +11 +15 +30 +10 +45 +7 +21 +11 +13 +8 +13 +13 +8 +13 +13 +34 +16 +11 +25 +12 +10 +13 +9 +27 +17 +24 +18 +30 +44 +33 +12 +10 +11 +21 +22 +14 +17 +24 +19 +30 +52 +7 +8 +14 +17 +19 +14 +7 +14 +21 +9 +30 +30 +21 +12 +18 +8 +17 +11 +7 +7 +18 +26 +14 +8 +16 +13 +8 +9 +13 +18 +7 +19 +24 +15 +31 +15 +12 +10 +17 +9 +7 +16 +14 +17 +21 +23 +18 +9 +14 +38 +14 +13 +12 +14 +9 +26 +13 +23 +19 +12 +9 +27 +9 +25 +9 +7 +15 +31 +19 +9 +26 +9 +18 +8 +18 +33 +11 +19 +11 +11 +56 +16 +13 +20 +17 +32 +19 +9 +19 +10 +12 +17 +18 +9 +13 +8 +12 +7 +11 +32 +11 +22 +10 +25 +30 +30 +7 +15 +7 +8 +15 +24 +20 +19 +22 +10 +9 +11 +19 +24 +11 +25 +15 +21 +18 +7 +9 +16 +25 +12 +13 +44 +10 +13 +9 +11 +22 +11 +26 +10 +9 +13 +12 +12 +8 +29 +8 +9 +22 +23 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k7.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k7.txt new file mode 100644 index 0000000..89bb5a1 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k7.txt @@ -0,0 +1,200 @@ +19 +22 +31 +-1 +21 +42 +-1 +23 +15 +15 +50 +19 +22 +26 +21 +17 +36 +43 +-1 +53 +28 +20 +18 +28 +54 +87 +25 +17 +30 +11 +20 +27 +17 +49 +16 +-1 +11 +24 +12 +36 +14 +23 +30 +18 +13 +46 +22 +17 +13 +26 +21 +17 +16 +13 +22 +12 +-1 +29 +23 +15 +113 +17 +-1 +43 +18 +23 +22 +12 +24 +35 +-1 +-1 +-1 +20 +57 +16 +27 +27 +13 +14 +35 +31 +31 +66 +22 +17 +36 +26 +20 +21 +15 +28 +21 +29 +27 +23 +-1 +-1 +-1 +-1 +10 +14 +18 +13 +28 +25 +26 +12 +24 +19 +39 +71 +28 +17 +16 +17 +16 +15 +16 +48 +35 +16 +29 +47 +28 +15 +11 +29 +19 +56 +55 +37 +25 +27 +26 +56 +41 +16 +27 +15 +45 +16 +27 +22 +16 +26 +20 +19 +32 +17 +21 +41 +19 +23 +19 +19 +21 +45 +28 +20 +18 +33 +24 +110 +21 +48 +72 +-1 +18 +45 +22 +23 +16 +45 +13 +29 +23 +45 +20 +42 +18 +16 +19 +32 +16 +57 +14 +20 +14 +30 +20 +30 +27 +13 +26 +27 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k8.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k8.txt new file mode 100644 index 0000000..c3f4643 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k8.txt @@ -0,0 +1,200 @@ +27 +18 +28 +-1 +-1 +-1 +-1 +220 +-1 +-1 +-1 +-1 +27 +-1 +24 +-1 +-1 +-1 +-1 +-1 +16 +-1 +19 +16 +-1 +-1 +-1 +25 +-1 +-1 +15 +34 +-1 +-1 +69 +16 +-1 +-1 +-1 +14 +39 +-1 +30 +24 +22 +267 +-1 +-1 +-1 +-1 +-1 +26 +-1 +34 +-1 +-1 +-1 +51 +-1 +61 +32 +-1 +-1 +-1 +19 +37 +23 +22 +55 +-1 +25 +-1 +-1 +27 +-1 +40 +-1 +-1 +21 +19 +38 +36 +-1 +15 +-1 +20 +-1 +26 +23 +24 +-1 +-1 +-1 +44 +-1 +36 +-1 +-1 +-1 +-1 +23 +25 +34 +-1 +-1 +-1 +-1 +32 +-1 +-1 +67 +31 +-1 +-1 +30 +-1 +-1 +-1 +-1 +15 +24 +29 +25 +38 +-1 +-1 +-1 +21 +29 +27 +-1 +59 +-1 +24 +21 +19 +22 +-1 +-1 +-1 +-1 +-1 +25 +17 +-1 +-1 +-1 +-1 +25 +-1 +48 +-1 +22 +-1 +-1 +15 +36 +-1 +30 +-1 +-1 +-1 +-1 +-1 +-1 +40 +22 +-1 +14 +-1 +29 +26 +-1 +31 +-1 +23 +-1 +22 +-1 +-1 +-1 +33 +23 +35 +25 +20 +-1 +-1 +30 +20 +-1 +-1 +29 +131 +24 +19 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k9.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k9.txt new file mode 100644 index 0000000..9ec5fdb --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_2x2_200_600gen_6popsize_k9.txt @@ -0,0 +1,200 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +30 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +35 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +18 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +21 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +19 +-1 +-1 +-1 +30 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k10.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k10.txt new file mode 100644 index 0000000..674ebd4 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k10.txt @@ -0,0 +1,200 @@ +92 +226 +139 +329 +-1 +-1 +-1 +-1 +-1 +206 +468 +-1 +88 +-1 +-1 +-1 +-1 +-1 +-1 +349 +-1 +-1 +-1 +156 +-1 +-1 +293 +-1 +90 +356 +-1 +409 +254 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +176 +247 +125 +69 +-1 +-1 +-1 +-1 +104 +-1 +-1 +-1 +168 +-1 +-1 +-1 +387 +-1 +-1 +-1 +-1 +-1 +-1 +393 +-1 +-1 +449 +327 +-1 +178 +208 +-1 +558 +75 +232 +346 +-1 +273 +223 +387 +-1 +-1 +-1 +333 +-1 +-1 +302 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +196 +-1 +-1 +-1 +-1 +194 +123 +138 +283 +174 +-1 +-1 +-1 +-1 +139 +-1 +-1 +301 +121 +269 +-1 +160 +-1 +167 +-1 +360 +55 +-1 +-1 +-1 +-1 +-1 +-1 +296 +-1 +306 +-1 +-1 +589 +74 +-1 +-1 +-1 +274 +142 +-1 +-1 +371 +197 +-1 +188 +304 +-1 +-1 +-1 +204 +63 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +461 +60 +-1 +468 +-1 +301 +-1 +-1 +351 +154 +-1 +304 +-1 +104 +558 +486 +-1 +230 +-1 +368 +-1 +-1 +-1 +101 +272 +-1 +-1 +-1 +-1 +248 +-1 +243 +391 +-1 +-1 +586 +561 +260 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k11.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k11.txt new file mode 100644 index 0000000..ed6c8d9 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k11.txt @@ -0,0 +1,200 @@ +418 +-1 +-1 +-1 +-1 +-1 +-1 +533 +-1 +411 +-1 +-1 +-1 +273 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +223 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +453 +-1 +-1 +-1 +-1 +-1 +485 +-1 +-1 +366 +284 +-1 +-1 +368 +161 +-1 +-1 +345 +-1 +130 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +325 +-1 +-1 +366 +-1 +-1 +-1 +-1 +-1 +336 +-1 +117 +-1 +-1 +-1 +-1 +94 +-1 +-1 +-1 +-1 +-1 +-1 +197 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +410 +-1 +-1 +168 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +537 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +110 +-1 +-1 +402 +466 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +365 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +156 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +143 +-1 +370 +-1 +-1 +325 +-1 +-1 +285 +-1 +433 +-1 +-1 +590 +-1 +-1 +-1 +-1 +561 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +540 +-1 +-1 +143 +-1 +389 +-1 +378 +-1 +-1 +-1 +107 +-1 +-1 +290 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k12.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k12.txt new file mode 100644 index 0000000..82ede9f --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k12.txt @@ -0,0 +1,200 @@ +253 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +263 +305 +-1 +-1 +-1 +-1 +339 +-1 +-1 +-1 +-1 +275 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +286 +-1 +-1 +-1 +-1 +294 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +221 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +524 +572 +-1 +547 +-1 +478 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +473 +363 +-1 +-1 +-1 +-1 +-1 +358 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +293 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +578 +-1 +-1 +502 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +291 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +333 +-1 +-1 +204 +-1 +-1 +-1 +555 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k13.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k13.txt new file mode 100644 index 0000000..1efcf13 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k13.txt @@ -0,0 +1,200 @@ +333 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +269 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +384 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +312 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +292 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +348 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +580 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +461 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +441 +522 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k14.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k14.txt new file mode 100644 index 0000000..72c5c2e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k14.txt @@ -0,0 +1,200 @@ +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +478 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +333 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +521 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k2.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k2.txt new file mode 100644 index 0000000..c3aaa70 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k2.txt @@ -0,0 +1,200 @@ +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k3.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k3.txt new file mode 100644 index 0000000..f79159e --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k3.txt @@ -0,0 +1,200 @@ +1 +1 +1 +1 +1 +1 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +3 +4 +1 +1 +1 +1 +1 +5 +9 +1 +3 +2 +1 +4 +4 +1 +1 +1 +1 +8 +1 +14 +3 +1 +1 +4 +1 +8 +1 +1 +1 +1 +5 +1 +1 +3 +1 +1 +1 +1 +1 +1 +15 +1 +1 +4 +1 +4 +1 +1 +1 +4 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +6 +5 +1 +1 +1 +3 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +24 +4 +1 +14 +27 +2 +1 +1 +1 +1 +3 +1 +1 +3 +1 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +6 +1 +1 +3 +8 +4 +1 +1 +1 +10 +1 +3 +1 +1 +1 +1 +1 +1 +3 +1 +15 +10 +3 +17 +4 +1 +1 +1 +1 +1 +1 +1 +7 +1 +1 +1 +1 +1 +1 +1 +1 +4 +1 +1 +1 +1 +3 +6 +1 +3 +1 +1 +1 +5 +1 +1 +1 +1 +1 +1 +3 +1 +7 +5 +1 +1 +1 +5 +3 +3 +5 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k4.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k4.txt new file mode 100644 index 0000000..0f8e6a3 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k4.txt @@ -0,0 +1,200 @@ +1 +1 +2 +1 +1 +1 +2 +1 +1 +2 +1 +1 +2 +1 +1 +8 +2 +16 +1 +1 +11 +10 +1 +2 +1 +4 +1 +1 +1 +1 +2 +1 +1 +1 +1 +38 +11 +28 +42 +18 +10 +8 +1 +1 +2 +1 +2 +1 +1 +9 +1 +2 +1 +1 +1 +2 +2 +2 +1 +3 +2 +40 +1 +3 +13 +1 +1 +1 +1 +3 +38 +2 +1 +11 +25 +10 +1 +7 +3 +8 +2 +2 +8 +34 +28 +27 +1 +11 +1 +1 +1 +1 +1 +2 +2 +2 +9 +10 +77 +60 +1 +2 +1 +1 +2 +1 +2 +2 +1 +1 +2 +1 +1 +1 +1 +1 +1 +3 +4 +9 +11 +1 +1 +1 +1 +1 +2 +14 +2 +1 +10 +1 +1 +2 +15 +2 +1 +1 +1 +3 +1 +1 +1 +1 +9 +2 +1 +15 +1 +24 +3 +1 +1 +6 +13 +1 +1 +13 +2 +19 +2 +15 +17 +1 +5 +2 +9 +16 +39 +11 +2 +2 +1 +3 +2 +1 +2 +1 +1 +4 +1 +1 +1 +1 +2 +2 +1 +3 +2 +1 +11 +1 +10 +1 +74 +79 +13 +44 +14 +36 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k5.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k5.txt new file mode 100644 index 0000000..5c55281 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k5.txt @@ -0,0 +1,200 @@ +2 +5 +7 +12 +17 +21 +10 +23 +12 +18 +2 +34 +2 +3 +4 +2 +2 +2 +5 +2 +2 +4 +3 +3 +5 +14 +4 +63 +5 +2 +2 +2 +2 +23 +2 +8 +4 +19 +2 +2 +2 +2 +22 +3 +41 +8 +12 +26 +5 +2 +9 +2 +2 +2 +9 +5 +8 +21 +2 +3 +78 +6 +12 +2 +2 +2 +44 +2 +2 +26 +8 +2 +99 +7 +6 +9 +75 +26 +6 +15 +2 +2 +2 +18 +26 +15 +2 +2 +2 +25 +2 +3 +2 +7 +4 +17 +12 +6 +24 +39 +2 +2 +2 +2 +4 +8 +6 +2 +10 +7 +2 +2 +17 +2 +18 +18 +6 +3 +2 +2 +16 +2 +34 +2 +7 +2 +2 +18 +2 +15 +46 +2 +2 +2 +2 +7 +2 +7 +2 +13 +7 +59 +29 +2 +2 +4 +26 +2 +2 +16 +2 +17 +6 +36 +19 +15 +18 +31 +2 +6 +5 +2 +2 +2 +18 +2 +75 +9 +2 +2 +3 +14 +23 +17 +25 +2 +2 +42 +55 +19 +2 +3 +2 +12 +5 +67 +17 +2 +2 +2 +2 +30 +2 +9 +6 +37 +17 +26 +229 +181 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k6.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k6.txt new file mode 100644 index 0000000..79e3113 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k6.txt @@ -0,0 +1,200 @@ +11 +15 +25 +16 +17 +28 +9 +17 +34 +19 +19 +19 +34 +15 +51 +8 +11 +48 +126 +9 +23 +11 +13 +9 +115 +139 +21 +42 +9 +17 +16 +21 +9 +16 +8 +51 +110 +25 +19 +12 +16 +25 +34 +22 +24 +28 +14 +18 +13 +39 +36 +19 +15 +16 +56 +44 +9 +18 +11 +35 +9 +23 +9 +29 +14 +8 +24 +36 +36 +22 +53 +23 +22 +61 +26 +17 +10 +9 +7 +10 +95 +8 +18 +31 +10 +7 +16 +7 +8 +25 +42 +27 +26 +7 +40 +47 +19 +25 +60 +139 +10 +11 +7 +29 +22 +28 +24 +42 +47 +18 +14 +42 +10 +32 +25 +12 +17 +8 +7 +16 +13 +21 +33 +39 +25 +84 +36 +10 +9 +18 +60 +36 +7 +10 +95 +33 +18 +38 +36 +18 +57 +45 +59 +190 +19 +46 +12 +33 +8 +47 +23 +9 +18 +9 +9 +14 +10 +24 +33 +13 +10 +12 +10 +38 +29 +15 +23 +31 +56 +59 +21 +25 +23 +7 +9 +43 +17 +35 +25 +9 +28 +26 +68 +15 +21 +19 +30 +24 +11 +62 +113 +21 +15 +19 +26 +121 +185 +198 +175 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k7.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k7.txt new file mode 100644 index 0000000..4b07dc3 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k7.txt @@ -0,0 +1,200 @@ +19 +23 +29 +68 +95 +46 +11 +14 +25 +84 +34 +170 +186 +43 +75 +14 +115 +178 +35 +18 +46 +114 +13 +91 +26 +241 +-1 +29 +22 +35 +-1 +-1 +497 +19 +64 +153 +46 +134 +22 +11 +105 +88 +19 +40 +14 +52 +20 +34 +149 +11 +77 +25 +15 +87 +-1 +43 +159 +24 +20 +56 +111 +17 +88 +168 +11 +22 +29 +347 +400 +31 +102 +62 +19 +69 +85 +89 +21 +111 +302 +126 +25 +333 +111 +21 +80 +65 +202 +22 +67 +29 +24 +38 +17 +-1 +35 +32 +66 +156 +-1 +-1 +22 +23 +33 +73 +53 +27 +134 +100 +179 +70 +11 +24 +18 +124 +26 +178 +12 +10 +34 +12 +191 +57 +24 +16 +82 +65 +228 +76 +13 +14 +107 +29 +19 +21 +95 +12 +17 +45 +19 +89 +319 +35 +165 +24 +28 +12 +17 +43 +34 +29 +39 +21 +23 +-1 +115 +29 +246 +-1 +24 +12 +11 +27 +32 +-1 +12 +27 +22 +13 +35 +14 +67 +66 +13 +205 +11 +22 +174 +19 +125 +20 +-1 +12 +-1 +52 +377 +440 +59 +126 +71 +46 +22 +27 +42 +122 +74 +108 +388 +-1 +-1 +501 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k8.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k8.txt new file mode 100644 index 0000000..34c9410 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k8.txt @@ -0,0 +1,200 @@ +35 +51 +52 +50 +34 +52 +158 +155 +304 +-1 +-1 +17 +-1 +245 +-1 +71 +80 +161 +-1 +147 +-1 +26 +16 +19 +-1 +47 +169 +152 +151 +36 +340 +99 +-1 +88 +69 +-1 +55 +196 +140 +22 +-1 +82 +120 +88 +48 +35 +232 +94 +127 +24 +270 +238 +183 +206 +27 +33 +193 +32 +92 +386 +150 +-1 +400 +32 +73 +52 +-1 +238 +-1 +204 +165 +63 +94 +-1 +152 +-1 +-1 +230 +257 +-1 +-1 +266 +42 +73 +61 +79 +-1 +105 +286 +87 +311 +26 +-1 +81 +-1 +533 +-1 +468 +569 +-1 +19 +19 +48 +44 +129 +208 +65 +22 +146 +42 +21 +52 +122 +390 +22 +-1 +48 +506 +-1 +51 +42 +274 +-1 +57 +135 +56 +139 +391 +17 +129 +369 +149 +98 +62 +62 +15 +14 +19 +-1 +308 +-1 +51 +228 +-1 +45 +175 +-1 +88 +-1 +183 +-1 +82 +24 +44 +319 +44 +-1 +101 +32 +38 +88 +200 +221 +33 +280 +17 +287 +149 +130 +421 +56 +139 +58 +41 +16 +44 +337 +-1 +176 +62 +103 +147 +136 +40 +335 +72 +102 +353 +14 +265 +66 +141 +-1 +-1 +333 +102 +236 +292 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k9.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k9.txt new file mode 100644 index 0000000..466e594 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_k9.txt @@ -0,0 +1,200 @@ +216 +362 +385 +67 +-1 +-1 +171 +198 +-1 +156 +-1 +-1 +67 +76 +83 +105 +-1 +296 +145 +302 +128 +226 +153 +-1 +225 +109 +109 +-1 +478 +-1 +98 +68 +165 +40 +-1 +97 +78 +124 +-1 +-1 +-1 +379 +-1 +63 +-1 +56 +146 +94 +-1 +-1 +75 +62 +-1 +127 +-1 +169 +-1 +54 +137 +253 +-1 +88 +423 +-1 +-1 +138 +-1 +-1 +-1 +37 +261 +353 +121 +-1 +98 +54 +-1 +95 +-1 +97 +117 +-1 +149 +50 +167 +-1 +360 +226 +118 +358 +482 +60 +49 +134 +228 +72 +-1 +-1 +580 +-1 +62 +209 +317 +157 +324 +210 +262 +-1 +-1 +-1 +-1 +76 +57 +270 +204 +203 +-1 +129 +-1 +228 +75 +-1 +-1 +-1 +-1 +240 +-1 +166 +96 +-1 +-1 +211 +-1 +-1 +96 +53 +-1 +443 +-1 +136 +-1 +51 +191 +-1 +312 +-1 +112 +-1 +-1 +-1 +75 +-1 +445 +-1 +278 +216 +-1 +64 +202 +412 +68 +-1 +-1 +47 +208 +163 +-1 +41 +109 +133 +-1 +177 +-1 +-1 +-1 +-1 +109 +326 +208 +109 +373 +71 +370 +215 +-1 +215 +-1 +-1 +154 +38 +160 +293 +111 +47 +-1 +203 +204 +-1 +-1 +-1 diff --git a/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_ktimes.txt b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_ktimes.txt new file mode 100644 index 0000000..f2b53f7 --- /dev/null +++ b/python/plots/how_many_generations/data_after_bug_fix/k_graphs/howManyGenerations_5x5_200_600gen_6popsize_ktimes.txt @@ -0,0 +1,26 @@ +CPU: i7-6700 @ 3.40 GHz (around 3.6 GHz at execution) +4 cores, 60% used + +- K2: 5.46s +- K3: 23.17s +- K4: 54.17s +- K5: 100.35s +- unknown + + +CPU: i5-8350U @ 1.70 GHz (around 2.5 GHz at execution) +4 cores, 80% used + +- K2: 3.13s +- K3: 11.70s +- K4: 44.09s +- K5: 108.74s +- K6: 232.39s +- K7: 521.61s +- K8: 3722.22s +- K9: 1655.97s +- K10: 2720.19s +- K11: 3210.61s +- K12: 3686.02s +- K13: 3449.03s +- K14: 4362.36s diff --git a/python/plots/how_many_generations/evolution.py b/python/plots/how_many_generations/evolution.py new file mode 100644 index 0000000..151e8f8 --- /dev/null +++ b/python/plots/how_many_generations/evolution.py @@ -0,0 +1,116 @@ +# Move this file to src/solver to start + +import logging +from random import random +from typing import Optional + +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + + +################################# Params ####################################### + +# Params used to generate "how_many_generations_nikolaus_10000" +# population_size=12 +# max_mutation_trials=30 +# mutation_extend_to_free_neighbors_probability=0.3 +# max_total = 10000 +# max_generations = 100 +# remove_redundancy_probability = 0.01 +# m = 2 # grid size +# n = 2 # grid size +# t = 4 # shore size + +params = EvolutionParams( + population_size=12, + max_mutation_trials=30, + mutation_extend_to_free_neighbors_probability=0.3 # should be <=0.5 +) + +max_total = 10000 +max_generations = 100 +remove_redundancy_probability = 0.01 + +# Chimera graph +m = 2 # grid size +n = 2 # grid size +t = 4 # shore size + + +################################ Setup ######################################## + +H = TestGraph.crossed_house() + + +############################### Evolution ###################################### + +def main_loop(): + with open('./out/how_many_generations.txt', 'w') as f: + for i in tqdm(range(max_total)): + logger.info('') + logger.info('#############') + logger.info('🎈 NEW MAIN 🎈') + logger.info('#############') + logger.info('') + logger.info(f'Calling main: {i}') + + generations_needed = main() + f.write(str(generations_needed) + '\n') + + +def main() -> int: + solver = EmbeddingSolver(H, m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + child = solver.generate_population_and_select(params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + + +if __name__ == "__main__": + main_loop() diff --git a/python/plots/how_many_generations/evolution_different_grid_sizes.py b/python/plots/how_many_generations/evolution_different_grid_sizes.py new file mode 100644 index 0000000..56eed06 --- /dev/null +++ b/python/plots/how_many_generations/evolution_different_grid_sizes.py @@ -0,0 +1,115 @@ +# Move this file to src/solver to start + +import logging +import multiprocessing +import time +from functools import partial +from random import random +from typing import Optional + +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.graph.undirected_graph import UndirectedGraphAdjList +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + + +################################# Params ####################################### + +params = EvolutionParams( + population_size=12, + max_mutation_trials=30, + mutation_extend_to_free_neighbors_probability=0.3 # should be <=0.5 +) + +max_total = 100 +max_generations = 100 +remove_redundancy_probability = 0.01 + +# Chimera graph +t = 4 # shore size + + +############################### Evolution ###################################### + +def different_grid_sizes(): + for m in range(9, 10): + print(f'Started with grid size {m}x{m}') + + graph = TestGraph.k(8) + params = [graph, m] + + start_time = time.time() + start_multiprocessing(params, 'k8_different_grid_sizes') + duration = time.time() - start_time + print(f'Duration for grid size {m}x{m}: {duration} s') + + +def start_multiprocessing(params, name: str): + with multiprocessing.Pool() as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, params), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/how_many_generations_{params[1]}x{params[1]}_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(params, j) -> int: + solver = EmbeddingSolver(params[0], params[1], params[1], t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + child = solver.generate_population_and_select(params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + + +if __name__ == "__main__": + different_grid_sizes() diff --git a/python/plots/how_many_generations/evolution_different_population_sizes.py b/python/plots/how_many_generations/evolution_different_population_sizes.py new file mode 100644 index 0000000..bc8864b --- /dev/null +++ b/python/plots/how_many_generations/evolution_different_population_sizes.py @@ -0,0 +1,115 @@ +# Move this file to src/solver to start + +import logging +import multiprocessing +import os +import time +from functools import partial +from random import random +from typing import Optional + +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + + +################################# Params ####################################### + +max_total = 100 +max_generations = 600 +remove_redundancy_probability = 0.01 + +# Chimera graph +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + + +############################### Evolution ###################################### + +def different_params(): + for population_size in range(1, 21): + print(f'Started population size {population_size}') + graph = TestGraph.k(8) + start_time = time.time() + start_multiprocessing((graph, population_size), f'k8_population_size_{population_size}') + duration = time.time() - start_time + print(f'Duration for population size {population_size}: {duration} s') + + +def start_multiprocessing(plot_params, name: str): + processes = multiprocessing.cpu_count() * int(os.getenv('CORE_PERCENTAGE', 75)) // 100 + with multiprocessing.Pool(processes) as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, plot_params), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/how_many_generations_{m}x{n}_1000_600_max_gen_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(plot_params, j) -> int: + solver = EmbeddingSolver(plot_params[0], m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver, plot_params) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver, plot_params) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + evo_params = EvolutionParams( + population_size=plot_params[1], + max_mutation_trials=30, + mutation_extend_to_free_neighbors_probability=0.3 # should be <=0.5 + ) + + child = solver.generate_population_and_select(evo_params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + + +if __name__ == "__main__": + different_params() diff --git a/python/plots/how_many_generations/evolution_multiprocessing.py b/python/plots/how_many_generations/evolution_multiprocessing.py new file mode 100644 index 0000000..381716b --- /dev/null +++ b/python/plots/how_many_generations/evolution_multiprocessing.py @@ -0,0 +1,113 @@ +# Move this file to src/solver to start + +import logging +import multiprocessing +import time +from functools import partial +from random import random +from typing import Optional + +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.graph.undirected_graph import UndirectedGraphAdjList +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + + +################################# Params ####################################### + +params = EvolutionParams( + population_size=12, + max_mutation_trials=30, + mutation_extend_to_free_neighbors_probability=0.3 # should be <=0.5 +) + +max_total = 1000 +max_generations = 100 +remove_redundancy_probability = 0.01 + +# Chimera graph +m = 5 # grid size +n = 5 # grid size +t = 4 # shore size + + +############################### Evolution ###################################### + +def do_all_k_graphs(): + for i in range(5, 13): + print(f'Started k{i}') + start_time = time.time() + start_multiprocessing(TestGraph.k(i), f'k{i}') + duration = time.time() - start_time + print(f'Duration for k{i}: {duration} s') + + +def start_multiprocessing(H: UndirectedGraphAdjList, name: str): + with multiprocessing.Pool() as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, H), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/how_many_generations_{m}x{n}_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(H: UndirectedGraphAdjList, i) -> int: + solver = EmbeddingSolver(H, m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + child = solver.generate_population_and_select(params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + + +if __name__ == "__main__": + do_all_k_graphs() diff --git a/python/plots/how_many_generations/evolution_multiprocessing_env.py b/python/plots/how_many_generations/evolution_multiprocessing_env.py new file mode 100644 index 0000000..31e9c9b --- /dev/null +++ b/python/plots/how_many_generations/evolution_multiprocessing_env.py @@ -0,0 +1,117 @@ +# Move this file to src/solver to start +# This is a file used for docker with environment variables + +import logging +import multiprocessing +import os +import time +from functools import partial +from random import random +from typing import Optional + +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.graph.undirected_graph import UndirectedGraphAdjList +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger +from tqdm import tqdm + +init_logger() +logger = logging.getLogger('evolution') + + +################################# Params ####################################### + +params = EvolutionParams( + population_size=int(os.getenv('POPULATION_SIZE', 4)), + max_mutation_trials=int(os.getenv('MAX_MUTATION_TRIALS', 30)), + mutation_extend_to_free_neighbors_probability=int( + os.getenv('PROB_EXTEND_TO_FREE_NEIGHBOR', 0.11)) # should be <=0.5 +) + +max_total = int(os.getenv('MAX_TOTAL', 1000)) +max_generations = int(os.getenv('MAX_GENERATIONS', 600)) +remove_redundancy_probability = int(os.getenv('PROB_REMOVE_REDUNDANCY', 0.01)) + +# Chimera graph +m = int(os.getenv('GRID_M', 5)) # grid size +n = int(os.getenv('GRID_N', 5)) # grid size +t = 4 # shore size + + +############################### Evolution ###################################### + +def do_all_k_graphs(): + for i in range(int(os.getenv('K_MIN', 5)), int(os.getenv('K_MAX', 30)) + 1): + print(f'Started k{i}') + start_time = time.time() + start_multiprocessing(TestGraph.k(i), f'k{i}') + duration = time.time() - start_time + print(f'Duration for k{i}: {duration}') + + +def start_multiprocessing(H: UndirectedGraphAdjList, name: str): + processes = multiprocessing.cpu_count() * int(os.getenv('CORE_PERCENTAGE', 90)) // 100 + with multiprocessing.Pool(processes) as pool: + # Multiprocessing + res = list(tqdm( + pool.imap_unordered(partial(do_once, H), range(max_total)), + total=max_total) + ) + + # Save to file + with open(f'./out/howManyGenerations_{m}x{n}_{max_total}_{max_generations}gen_{params.population_size}popsize_{name}.txt', 'w') as f: + for generations_needed in res: + f.write(str(generations_needed) + '\n') + + +def do_once(H: UndirectedGraphAdjList, i) -> int: + solver = EmbeddingSolver(H, m, n, t) + + # --- Init + solver.initialize_embedding() + + if solver.found_embedding(): + print('🎉 Directly found embedding after initialization') + return 0 + + # --- Start solver + for i in range(max_generations): + child = do_one_generation(i, solver) + + if not child: + logger.info('🔳 Stopping algorithm...') + return -1 + + solver.commit(child) + + # Check if done + if child.is_valid_embedding(): + child.remove_redundancy() + return i+1 + else: + logger.info('✅ Generation passed') + + return -1 + + +def do_one_generation(i: int, solver: EmbeddingSolver) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + child = solver.generate_population_and_select(params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Main ########################################## + + +if __name__ == "__main__": + do_all_k_graphs() diff --git a/python/plots/how_many_generations/how_many_embedded.py b/python/plots/how_many_generations/how_many_embedded.py new file mode 100644 index 0000000..61f6d46 --- /dev/null +++ b/python/plots/how_many_generations/how_many_embedded.py @@ -0,0 +1,63 @@ +import matplotlib.pyplot as plt +import matplotlib.ticker as ticker +import numpy as np + +names = [str(i) for i in range(1, 8)] +embedded = [] +average_generations = [] + +# --- Prepare data +for name in names: + filename = f'./data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize{name}.txt' + with open(filename, 'r') as f: + data = f.read().splitlines() + data = [int(value) for value in data] + # unique, counts = np.unique(data, return_counts=True) + embedded.append(100 - data.count(-1)) + + data_embedded = [value for value in data if value != -1] + average_generations.append(np.average(data_embedded)) + + +# --- Plot setup +plt.rcParams.update({ + "text.usetex": True, + "font.family": "Helvetica" +}) + +# https://stackoverflow.com/a/39566040/9655481 +MEDIUM_SIZE = 8 +MEDIUM_SIZE = 14 +BIGGER_SIZE = 16 + +plt.rc('font', size=MEDIUM_SIZE) # controls default text sizes +plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title +plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels +plt.rc('xtick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('ytick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('legend', fontsize=MEDIUM_SIZE) # legend fontsize +plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + +# --- Plot +color = '#E53054' +fig, ax = plt.subplots(figsize=(10, 6)) +ax.set_ylabel('Occurrences of valid embeddings') +ax.set_xlabel('Probability of using the "extend to free neighbor" mutation') +ax.set_ylim(0, 100) +# ax.xaxis.set_major_locator(ticker.MultipleLocator(5)) +# ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) +ax.plot(names, embedded, color, marker='o') + +# Write average number of generations needed next to data point +# https://queirozf.com/entries/add-labels-and-text-to-matplotlib-plots-annotation-examples +for i, v in enumerate(average_generations): + ax.annotate(str(round(v, 0)), + (i, embedded[i]), + textcoords='offset points', + xytext=(0, -22), + horizontalalignment='center') + +# ax.set_title('Generations needed for the crossed house puzzle') +plt.tight_layout() +plt.show() diff --git a/python/plots/how_many_generations/how_many_embedded_and_generations.py b/python/plots/how_many_generations/how_many_embedded_and_generations.py new file mode 100644 index 0000000..d6c9d4a --- /dev/null +++ b/python/plots/how_many_generations/how_many_embedded_and_generations.py @@ -0,0 +1,106 @@ +import matplotlib.pyplot as plt +import matplotlib.ticker as ticker +import numpy as np + +names = [str(i) for i in range(2, 15)] +# names = np.linspace(0.0, 1.0, num=20) +# names = [str(round(v, 2)) for v in names] +# names.append('0.22') +# names.append('0.24') +# names.append('0.27') +# names.append('0.29') +# names.append('0.31') +# names.append('0.33') +# names.append('0.36') +# names.append('0.38') +# names.append('0.4') + +embedded = [] +average_generations = [] +max_total = 300 + +# --- Prepare data +for name in names: + # filename = f'./data_after_bug_fix/k8_popsize/howManyGenerations_5x5_10_600gen_k8popsize{name}.txt' + # filename = f'./data_after_bug_fix/k8_probabilities_free/howManyGenerations_5x5_20_600gen_k80.0-0.2prob{name}.txt' + # filename = f'./data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k{name}.txt' + # filename = f'./data_after_bug_fix/k8_probabilities_free/server-run/howManyGenerations_5x5_300_600gen_k8prob{name}.txt' + filename = f'./data_after_bug_fix/k8_popsize/server-run/howManyGenerations_5x5_300_600gen_k8popsize{name}.txt' + with open(filename, 'r') as f: + data = f.read().splitlines() + data = [int(value) for value in data] + # unique, counts = np.unique(data, return_counts=True) + embedded.append(max_total - data.count(-1)) + + data_embedded = [value for value in data if value != -1] + average_generations.append(np.average(data_embedded)) + + +# --- Plot setup +plt.rcParams.update({ + "text.usetex": True, + "font.family": "Helvetica" +}) + +# https://stackoverflow.com/a/39566040/9655481 +MEDIUM_SIZE = 8 +MEDIUM_SIZE = 14 +BIGGER_SIZE = 16 + +plt.rc('font', size=MEDIUM_SIZE) # controls default text sizes +plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title +plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels +plt.rc('xtick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('ytick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('legend', fontsize=MEDIUM_SIZE) # legend fontsize +plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + +# --- Plot +fig, ax = plt.subplots(figsize=(11, 6)) +ax.set_xlabel('Population size') +# ax.set_xlabel('Probability for "extend to free neighbors" heuristic') +# ax.set_xlabel('K graph') + +# Average generations +color_blue = '#2981B3' +# color_blue = '#2EB4FF' +ax.set_ylabel('Average number of generations needed', color=color_blue) +# ax.plot(names, average_generations, color=color_blue, marker='o') +ax.bar(names, average_generations, color=color_blue, fill=False, edgecolor=color_blue) +ax.tick_params(axis='y', labelcolor=color_blue) + + +ax2 = ax.twinx() +# Number embedded +color_red = '#E53054' +# color_red = '#FF4A6D' +ax2.set_ylabel('Occurrences of valid embeddings', color=color_red) +ax2.set_ylim(0, max_total+5) +# ax.xaxis.set_major_locator(ticker.MultipleLocator(5)) +# ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) +ax2.plot(names, embedded, color=color_red, marker='o') +ax2.tick_params(axis='y', labelcolor=color_red) + + +# Write average number of generations needed next to data point +# https://queirozf.com/entries/add-labels-and-text-to-matplotlib-plots-annotation-examples +for i, embedded_count in enumerate(embedded): + percent_embedded = round(embedded_count / max_total * 100, 2) + ax2.annotate(f'{percent_embedded}\,\%', + (i, embedded_count), + textcoords='offset points', + xytext=(16, 10), + horizontalalignment='center', + color=color_red, + fontsize=14) +# for i, v in enumerate(average_generations): +# ax.annotate(str(round(v, 0)), +# (i, embedded[i]), +# textcoords='offset points', +# xytext=(0, -22), +# horizontalalignment='center') + +# ax.set_title('Generations needed for the crossed house puzzle') +plt.tight_layout() +plt.show() diff --git a/python/plots/how_many_generations/how_many_generations.py b/python/plots/how_many_generations/how_many_generations.py new file mode 100644 index 0000000..abdaeea --- /dev/null +++ b/python/plots/how_many_generations/how_many_generations.py @@ -0,0 +1,45 @@ +import matplotlib.pyplot as plt +import matplotlib.ticker as ticker +import numpy as np + +# --- Prepare data +with open('./data/how_many_generations_5x5_k6.txt', 'r') as f: + data = f.read().splitlines() + data = [int(value) for value in data] + +unique, counts = np.unique(data, return_counts=True) + + +# --- Plot setup +plt.rcParams.update({ + "text.usetex": True, + "font.family": "Helvetica" +}) + +# https://stackoverflow.com/a/39566040/9655481 +MEDIUM_SIZE = 8 +MEDIUM_SIZE = 10 +BIGGER_SIZE = 12 + +plt.rc('font', size=MEDIUM_SIZE) # controls default text sizes +plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title +plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels +plt.rc('xtick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('ytick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('legend', fontsize=MEDIUM_SIZE) # legend fontsize +plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + +# --- Plot +fig, ax = plt.subplots(figsize=(10, 6)) +ax.axhline(0, color='grey', linewidth=0.8) +ax.set_ylabel('Scores', fontsize=18) +ax.set_ylabel('Occurrences') +ax.set_xlabel('Generations needed', fontsize=18) +ax.xaxis.set_major_locator(ticker.MultipleLocator(5)) +ax.xaxis.set_minor_locator(ticker.MultipleLocator(1)) +ax.bar(unique, counts) + +# ax.set_title('Generations needed for the crossed house puzzle') +plt.tight_layout() +plt.show() diff --git a/python/plots/how_many_generations/how_many_generations_all.py b/python/plots/how_many_generations/how_many_generations_all.py new file mode 100644 index 0000000..3233d65 --- /dev/null +++ b/python/plots/how_many_generations/how_many_generations_all.py @@ -0,0 +1,104 @@ +from collections import namedtuple + +import matplotlib.pyplot as plt +import matplotlib.ticker as ticker +import numpy as np + +names = [str(i) for i in range(6, 14)] + + +# --- Prepare data +Data = namedtuple('Data', ['unique', 'counts']) +datas = [] +for name in names: + # filename = f'./data/population_size_100_runs/how_many_generations_5x5_100_600_max_gen_k8_population_size_{name}.txt' + filename = f'./data_after_bug_fix/k_graphs/howManyGenerations_16x16_100_600gen_6popsize_k{name}.txt' + with open(filename, 'r') as f: + data = f.read().splitlines() + data = [int(value) for value in data] + unique, counts = np.unique(data, return_counts=True) + datas.append(Data(unique, counts)) + + +# --- Plot setup +plt.rcParams.update({ + "text.usetex": True, + "font.family": "Helvetica" +}) + +# https://stackoverflow.com/a/39566040/9655481 +MEDIUM_SIZE = 8 +MEDIUM_SIZE = 14 +BIGGER_SIZE = 16 + +plt.rc('font', size=MEDIUM_SIZE) # controls default text sizes +plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title +plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels +plt.rc('axes', titlesize=BIGGER_SIZE) # fontsize of the x and y labels +plt.rc('xtick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('ytick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('legend', fontsize=MEDIUM_SIZE) # legend fontsize +# plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + +# --- Plot +rows = 2 +cols = 4 +fig, axs = plt.subplots(rows, cols, figsize=(14, 9)) + +i = 0 +for r in range(rows): + for c in range(cols): + ax = axs[r, c] + + if i == len(datas): + break + + # color = '#2981B3' + color = '#E53054' + ax.bar(datas[i][0], datas[i].counts, color=color) + # ax.axhline(0, color='grey', linewidth=0.8) + # ax.set_title(f'population size {names[i]}') + ax.set_title(f'$K_{{{names[i]}}}$') + + # Same scale for most subfigures + # maximum = max(datas[i].unique) + # print(maximum) + # if maximum < 100: + # ax.set_xlim(-5, 100) + + ax.set_xlim(left=-5) + if i >= 2: + ax.set_xlim(left=-30) + + # major = 5 if max(datas[i].unique) <= 60 else 10 + # ax.xaxis.set_major_locator(ticker.MultipleLocator(major)) + + # minor = 1 if max(datas[i].unique) <= 60 else 5 + # ax.xaxis.set_minor_locator(ticker.MultipleLocator(minor)) + + # https://stackoverflow.com/a/38096332/9655481 + ax.yaxis.get_major_locator().set_params(integer=True) + ax.xaxis.set_minor_locator(ticker.AutoMinorLocator()) + ax.yaxis.set_minor_locator(ticker.AutoMinorLocator()) + + # y_max = 60 if r == 0 else 70 + # ax.set_ylim(top=75) + # if max(datas[i].counts) >= 70: + # ax.set_ylim(top=90) + # else: + # ax.set_ylim(top=75) + # ax.set_xlim(0, 100) + + i += 1 + +# Label +# axs[0, 0].set_xlim(-5, 20) + +axs[1, 0].set_ylabel('Occurrences') +axs[1, 0].set_xlabel('Generations needed') + +# ax.set_title('Generations needed for the crossed house puzzle') +plt.subplots_adjust(left=0.05, top=0.96, right=0.98, bottom=0.06, hspace=0.3, wspace=0.25) +# plt.tight_layout(pad=0.2, w_pad=0.1, h_pad=0.1, rect=(0.05, 0.05, 0.95, 0.95)) +plt.show() diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 0000000..485c755 --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1,5 @@ +dwave-networkx==0.8.10 +matplotlib==3.4.3 +networkx==2.6.3 +numpy==1.21.0 +tqdm==4.62.3 \ No newline at end of file diff --git a/python/src/drawing/color_util.py b/python/src/drawing/color_util.py new file mode 100644 index 0000000..f7de6f7 --- /dev/null +++ b/python/src/drawing/color_util.py @@ -0,0 +1,28 @@ +def change_brightness(color, amount=1): + """ + Lightens/Darkens the given color by multiplying luminosity by the given amount. + Input can be matplotlib color string, hex string, or RGB tuple. + + Examples: + >> change_brightness('g', 0.3) + >> change_brightness('#F034A3', 0.6) + >> change_brightness((.3,.55,.1), 0.5) + """ + # adapted from + # https://gist.github.com/ihincks/6a420b599f43fcd7dbd79d56798c4e5a + # https://stackoverflow.com/a/49601444/9655481 + + import colorsys + + import matplotlib.colors as mc + import numpy as np + + try: + c = mc.cnames[color] + except: + c = color + + c = np.array(colorsys.rgb_to_hls(*mc.to_rgb(c))) + hls = (c[0], max(0, min(1, amount * c[1])), c[2]) + rgb = colorsys.hls_to_rgb(*hls) + return mc.to_hex(rgb) diff --git a/python/src/drawing/draw.py b/python/src/drawing/draw.py index b46231a..bb6dba0 100644 --- a/python/src/drawing/draw.py +++ b/python/src/drawing/draw.py @@ -1,95 +1,137 @@ import dwave_networkx as dnx import matplotlib.pyplot as plt import networkx as nx +from src.drawing.color_util import change_brightness +from src.drawing.node_colors import get_supernode_color +default_embedded_color = '#6B6B6A' -class Draw(): - def __init__(self): - self.pos = { - 0: (0., -0.5), - 1: (0.25, -0.5), - 2: (0.75, -0.5), - 3: (1, -0.5), - 4: (0.5, 0.), - 5: (0.5, -0.25), - 6: (0.5, -0.75), - 7: (0.5, -1.) - } - self.chain_colors = ['#55C1D9', '#F29E38', - '#F23827', '#D748F5', '#39DBC8'] +class DrawEmbedding(): - def draw_chimera_graph(self, m, n, t): + def init_figure(self): + self.fig = plt.figure() + plt.subplots_adjust(left=0.0, right=1.0, + bottom=0.0, top=1.0, + wspace=0.1, hspace=0.1) + + def __init__(self, m, n, t): + self.total_steps = 0 + + # https://matplotlib.org/stable/gallery/subplots_axes_and_figures/figure_size_units.html + self.px = 1/plt.rcParams['figure.dpi'] # pixel in inches + plt.rcParams.update({ + 'axes.titlesize': 22, + 'text.usetex': False, + 'font.family': 'Helvetica' + }) + + self.col = 0 + self.m = m + self.n = n + + self.init_chimera_graph(m, n, t) + + def init_chimera_graph(self, m, n, t): + self.chimera_G = dnx.chimera_graph(m, n, t) + self.pos_chimera = dnx.chimera_layout(self.chimera_G) + + def draw_chimera_graph(self): """Draws a Chimera graph.""" - G = dnx.chimera_graph(m, n, t) - pos_chimera = dnx.chimera_layout(G) - nx.draw_networkx(G, - pos=pos_chimera, + + # Nodes & Edges + nx.draw_networkx(self.chimera_G, + pos=self.pos_chimera, width=2, with_labels=False, - node_color='#858585', - edge_color='#BABABA') - # dnx.draw_chimera(G, - # width=2, - # node_color='#858585', - # edge_color='#BABABA') - - def _draw(self, nodes, edges, mapping_G_to_H): + node_color='#C8C8C8', + edge_color='#C8C8C8') + + # Labels + # Shift labels + pos_labels = {node: [pos[0] - 0.020, pos[1]] + for (node, pos) in self.pos_chimera.items()} + nx.draw_networkx_labels(self.chimera_G, + pos=pos_labels, + font_size=8, + font_color='#858585') + + def draw_embedding(self, nodes: set[int], edges: set[tuple[int, int, int]], + mapping_G_to_H): """Draws the embedding onto the Chimera graph. - Arguments - --------- - - nodes: nodes list - - edges: tuple (from, to, chain) + Args: + nodes (set[int]): nodes + edges (set[tuple[int, int, int]]): set of tuples (node1, node2, chain) """ labels = {} for node in nodes: labels[node] = mapping_G_to_H[node] - chains = [edge[2] for edge in edges] - for chain in range(max(chains)+1): - chain_edges = [(edge[0], edge[1]) - for edge in edges if edge[2] == chain] - - graph = nx.Graph() - graph.add_nodes_from(nodes) - graph.add_edges_from(chain_edges) - - chain_color = self.chain_colors[chain % len(self.chain_colors)] - nx.draw_networkx(graph, - labels=labels, - pos=self.pos, - width=3, - style='solid', - node_color='#363636', - edge_color=chain_color, - font_color='whitesmoke', - font_size=15, - font_family='serif') - - def draw_embedding(self, nodes, edges, mapping_G_to_H): - self._draw(nodes, edges, mapping_G_to_H) + G = nx.Graph() + G.add_nodes_from(nodes) + + # Labels + nx.draw_networkx_labels(G, + pos=self.pos_chimera, + labels=labels, + font_size=14, + font_color='whitesmoke', + font_family='serif') + + # Nodes & Edges + remember_nodes_in_chain = [] + for edge in edges: + node1 = edge[0] + node2 = edge[1] + + # Color edges inside a supernode with the same color + # and between supernodes with the first color + node1_H = mapping_G_to_H[node1] + node2_H = mapping_G_to_H[node2] + + # Nodes + self.draw_node(node1, get_supernode_color(node1_H)) + self.draw_node(node2, get_supernode_color(node2_H)) + + # Edges + G.add_edge(node1, node2) + chain_color = get_supernode_color(node1_H)\ + if node1_H == node2_H else default_embedded_color + nx.draw_networkx_edges(G, + pos=self.pos_chimera, + width=3, + style='solid', + edge_color=chain_color) + G.remove_edge(node1, node2) + + def draw_node(self, node: int, color): + G = nx.Graph() + G.add_node(node) + nx.draw_networkx_nodes(G, + pos=self.pos_chimera, + node_color=change_brightness(color, amount=0.8), + linewidths='2', + edgecolors=color) + + def draw_chimera_and_embedding(self, nodes: set[int], edges: set[tuple[int, int, int]], + mapping_G_to_H): + self.draw_chimera_graph() + self.draw_embedding(nodes, edges, mapping_G_to_H) + + def show_embedding(self): plt.show() - ############################ Big Plot ###################################### + ############################ Embedding step ################################ - def init_big_plot(self, row_count): - self.big_plot_row_count = row_count - # https://matplotlib.org/stable/gallery/subplots_axes_and_figures/figure_size_units.html - px = 1/plt.rcParams['figure.dpi'] # pixel in inches - fig = plt.figure(figsize=(row_count*200*px*3, row_count*200*px*3)) - plt.axis('off') - plt.subplots_adjust(left=0.0, right=1.0, bottom=0.0, top=1.0, - wspace=0.0, hspace=0.0) - self.big_plot_index = 1 # to start with (gets incremented later) - - def draw_to_big_plot(self, nodes, edges, mapping_G_to_H): - plt.subplot(self.big_plot_row_count, - self.big_plot_row_count, self.big_plot_index) - self.draw_chimera_graph(1, 1, 4) - self._draw(nodes, edges, mapping_G_to_H) - plt.draw() - self.big_plot_index += 1 - - def save_big_plot(self, filename): - plt.savefig(f'./{filename}.svg') + def draw_whole_embedding_step(self, nodes: set[int], edges: set[tuple[int, int, int]], + mapping_G_to_H, title=''): + self.init_figure() + self.fig.suptitle(title, fontsize=16) + self.draw_chimera_and_embedding(nodes, edges, mapping_G_to_H) + self.total_steps += 1 + + def save_and_clear(self, path): + self.fig.set_size_inches(self.m*3, self.n*3) + self.fig.savefig(path, bbox_inches='tight') + plt.close(self.fig) diff --git a/python/src/drawing/node_colors.py b/python/src/drawing/node_colors.py new file mode 100644 index 0000000..8db660f --- /dev/null +++ b/python/src/drawing/node_colors.py @@ -0,0 +1,23 @@ +supernode_colors = [ + '#FF4A6D', '#2EB4FF', '#FF8C36', '#2BD8B7', '#AE1CFF', + '#2BC2D6', '#DBDE5D', '#11F0EB', '#7D2EFF', '#2B76EF', + '#E0165C', '#3CDE73', '#F23827', '#F29E38', '#D33EDB', + '#0EA54E' +] + +remember_colors = dict() +i = 0 + + +def get_supernode_color(node_H: int): + global i + + if node_H in remember_colors: + return remember_colors[node_H] + + # Choose color and remember it + color = supernode_colors[i % len(supernode_colors)] + remember_colors[node_H] = color + i += 1 + + return color diff --git a/python/src/embedding/articulation_point.py b/python/src/embedding/articulation_point.py new file mode 100644 index 0000000..735abeb --- /dev/null +++ b/python/src/embedding/articulation_point.py @@ -0,0 +1,66 @@ + +from src.embedding.embedding import EmbeddingGraph +from src.util.util import get_first_from + + +class ArticulationPointCalculator: + + def __init__(self, G: EmbeddingGraph) -> None: + self.G = G + + def calc_articulation_points(self, nodes: set[int]) -> set[int]: + """Returns the articulation points aka "cut nodes" in the given subgraph""" + self.nodes = nodes + + self.time = 0 + self.discovery_time = {node: -1 for node in nodes} + self.min_level = {node: -1 for node in nodes} + self.articulation_points = set() + + self.visited = {node: False for node in nodes} + self.parent = {node: -1 for node in nodes} + self._dfs_articulation_points(get_first_from(nodes)) + + return self.articulation_points.copy() + + def _dfs_articulation_points(self, node: int) -> None: + self.visited[node] = True + + children_count = 0 + self.discovery_time[node] = self.time + self.time += 1 + self.min_level[node] = self.time + + # DFS recursion + for neighbor in self.G.get_neighbor_nodes(node): + # Only consider nodes in subgraph + if neighbor not in self.nodes: + continue + + if not self.visited[neighbor]: + children_count += 1 + self.parent[neighbor] = node + # Recurse + self._dfs_articulation_points(neighbor) + + # Check if the subtree rooted with neighbor has a connection to + # one of the ancestors of node + self.min_level[node] =\ + min(self.min_level[node], self.min_level[neighbor]) + + # Check if articulation point + # Node is an articulation point in the following cases + if self.parent[node] == -1: + # (1) node is root of DFS tree and has two or more children + if children_count > 1: + self.articulation_points.add(node) + else: + # (2) If node is not root and discovery time of node is less + # or equal than min_level of one of its children + if self.discovery_time[node] <= self.min_level[neighbor]: + self.articulation_points.add(node) + + elif neighbor != self.parent[node]: # only if there is a "back-edge" + # Update min_level of node + self.min_level[node] =\ + min(self.min_level[node], self.discovery_time[neighbor]) diff --git a/python/src/embedding/embedding.py b/python/src/embedding/embedding.py index b2de2b1..70ae8d7 100644 --- a/python/src/embedding/embedding.py +++ b/python/src/embedding/embedding.py @@ -1,121 +1,151 @@ import itertools +import logging from copy import deepcopy -from typing import List from src.embedding.graph_mapping import GraphMapping -from src.graphs.chimera_graph import ChimeraGraphLayout, GraphEmbedding -from src.graphs.undirected_graphs import UndirectedGraphAdjList +from src.graph.chimera_graph import ChimeraGraphLayout +from src.graph.embedding_graph import EmbeddingGraph +from src.graph.undirected_graph import UndirectedGraphAdjList +from src.embedding.articulation_point import ArticulationPointCalculator + +logger = logging.getLogger('evolution') -########################### Embedding blueprint ################################ class Embedding(): - def __init__(self, H: UndirectedGraphAdjList): + def __init__(self, H: UndirectedGraphAdjList, m, n, t): + """Initializes an Embedding. - # TODO: explain difference (!) - crucial for understanding + Args: + H (UndirectedGraphAdjList): The minor Graph to embed + """ + # --- Minor H self.H = H - self.G_layout = ChimeraGraphLayout() - self.G_embedding = GraphEmbedding(8) - self.G_embedding_view = GraphEmbedding(H.nodes_count) - self.mapping = GraphMapping() + # --- Layout Graph + # Graph to embed H onto + self.G_layout = ChimeraGraphLayout(m, n, t) + + # --- Embedding Graph + # Full graph: nodes are labeled according to G + self.G_embedding = EmbeddingGraph(self.G_layout.get_size()) + # View graph: nodes are labeled according to H + self.G_embedding_view = EmbeddingGraph(H.nodes_count) - def get_embedded_nodes(self) -> List: - return self.G_embedding.get_embedded_nodes() + self.mapping = GraphMapping(H.nodes_count) - def get_reachable_neighbors(self, from_node): - return self.G_layout.get_neighbor_nodes(from_node) + def get_embedded_nodes(self) -> set[int]: + """Returns all embedded nodes. + + Returns: + set[int]: The embedded nodes. + """ + embedded_nodes = self.G_embedding.get_embedded_nodes() + if not embedded_nodes: + raise Exception('No nodes embedded yet') + return embedded_nodes - def get_free_neighbors(self, from_node) -> List: - neighbors = self.G_layout.get_neighbor_nodes(from_node) + def get_reachable_neighbors(self, source): + return self.G_layout.get_neighbor_nodes(source) + + def get_free_neighbors(self, source) -> set[int]: + neighbors = self.G_layout.get_neighbor_nodes(source) neighbors_used = self.G_embedding.get_embedded_nodes() - neighbors_free = [neighbor for neighbor in neighbors - if neighbor not in neighbors_used] + neighbors_free = {neighbor for neighbor in neighbors + if neighbor not in neighbors_used} if not neighbors_free: - raise NoFreeNeighborNodes(from_node) + raise NoFreeNeighborNodes(source) return neighbors_free - def get_connected_neighbors(self, from_node) -> List: - return self.G_embedding.get_neighbor_nodes(from_node) + def get_embedded_neighbors(self, source) -> set[int]: + return self.G_embedding.get_neighbor_nodes(source) - def embed_edge(self, node_from, node_to) -> None: - self.G_embedding.embed_edge(node_from, node_to) - node_from_H = self.mapping.add_mapping_new_node_H(node_from) - node_to_H = self.mapping.add_mapping_new_node_H(node_to) - self.G_embedding_view.embed_edge(node_from_H, node_to_H) + def embed_edge(self, node1, node2) -> None: + # Embed edge + if not self.G_layout.exists_edge(node1, node2): + raise NoViableEdge(node1, node2) + self.G_embedding.embed_edge(node1, node2) - def remove_edge_inconsistently(self, from_node, to_node): - self.G_embedding.remove_edge(from_node, to_node) + # Adjust view graph + supernode1 = self.mapping.get_supernode_create_if_not_available(node1) + supernode2 = self.mapping.get_supernode_create_if_not_available(node2) + if supernode1 != supernode2: # avoid unnecessary selfloops + self.G_embedding_view.embed_edge(supernode1, supernode2) - def add_chain_to_used_nodes(self, from_node, to_node, to_node_new=None): - """ - Adds a new chain. Does NOT check if this chain is even possible in the - graph at the moment. TODO: "insource" the check to this class + # def embed_edge_without_mapping(self, node1, node2) -> None: + # # TODO: add warning on how to use this as this will leave inconsistent states + # # if not called correctly + # if not self.G_layout.exists_edge(node1, node2): + # raise NoViableEdge(node1, node2) + # self.G_embedding.embed_edge(node1, node2) + + def embed_edge_with_mapping(self, source_H, source_G, target_H, target_G) -> None: + # TODO: add warning that this will overwrite the mapping (!) + # not extend it + self.G_embedding.embed_edge(source_G, target_G) + self.mapping.set_mapping(source_H, source_G) + self.mapping.set_mapping(target_H, target_G) + self.G_embedding_view.embed_edge(source_H, target_H) + + def remove_edge_inconsistently(self, source, target): + self.G_embedding.remove_edge(source, target) + + def exists_edge(self, source, target): + return self.G_layout.exists_edge(source, target) + + def get_supernode(self, node_G) -> int: + return self.mapping.get_node_H(node_G) + + def get_nodes_in_supernode(self, node_H) -> set[int]: + return self.mapping.get_nodes_G(node_H) + + def get_nodes_in_supernode_of(self, node_G) -> set[int]: + """Returns the nodes in the supernode that ``node_G`` is in. + + Note that ``node_G`` will be included in the resulting set. """ - # --- Adjust mapping - # mapping for from_node stays the same - from_node_H = self.mapping.get_node_H(node_G=from_node) - # mapping for to_node is adjusted so that from_node_H maps to from_node AND to_node - to_node_H = self.mapping.get_node_H(node_G=to_node) - - self.mapping.remove_mapping(to_node_H, to_node) - self.mapping.extend_mapping(from_node_H, to_node) - self.mapping.extend_mapping(to_node_H, to_node_new) - - # --- Adjust embedding - # Delete all edges from node_to and add respective edges from node_to_new - to_node_connected_neighbors = self.get_connected_neighbors(to_node) - self.G_embedding.delete_all_edges_from_node(to_node) - for prev_connected_neighbor in to_node_connected_neighbors: - # Avoid edge from node to itself - if prev_connected_neighbor in [from_node, to_node_new]: - continue - - # to_node_new might be a chain itself - nodes_in_chain = self.G_embedding.get_nodes_in_same_chain( - to_node_new) - embedded = False - for node_in_chain in nodes_in_chain: - if self.G_layout.exists_edge(prev_connected_neighbor, node_in_chain): - self.G_embedding.embed_edge( - prev_connected_neighbor, node_in_chain - ) - embedded = True - break - if not embedded: - raise RuntimeError('Error adding a chain to used nodes') - - # --- Chain - self.G_embedding.add_chain(from_node, to_node) - # Add missing edge node_to---node_to_new - self.G_embedding.embed_edge(to_node, to_node_new) - - # TODO: adjust embedding for self.G_embedding_small_view (???) - - def extend_one_node_to_chain(self, frm, to, extend_G): - """Extends one node to a chain. - - Note that en edge from replace_G to frm must be viable. TODO: add a check + supernode = self.get_supernode(node_G) + return self.get_nodes_in_supernode(supernode) + + def construct_supernode(self, source: int, target: int) -> None: + # Embed edge + self.G_embedding.embed_edge(source, target) + + # Remove target from previous chain + self.try_remove_from_supernode(target) + + # Add to new chain + source_supernode = self.mapping.get_supernode_create_if_not_available(source) + self.mapping.extend_mapping(source_supernode, target) + + def try_remove_from_supernode(self, node: int): + """Removes node from its supernode, leaving us with an inconsistent state. + + If ``node`` was in no supernode, we silently do nothing. """ - extend_H = self.mapping.get_node_H(node_G=extend_G) - self.mapping.extend_mapping(extend_H, frm) - self.mapping.extend_mapping(extend_H, to) - chain = self.G_embedding.add_chain(frm, to) - # avoid inconsistent state - self.G_embedding.embed_edge(extend_G, frm, chain=chain) + try: + supernode = self.get_supernode(node) + self.mapping.remove_mapping(supernode, node) + except KeyError: + pass def is_valid_embedding(self) -> bool: - for frm in self.H._get_nodes(): - expected_tos = self.H._get_neighbor_nodes(frm) - actual_tos = self.G_embedding_view.get_neighbor_nodes(frm) - if actual_tos != expected_tos: + for source in self.H.get_nodes(): + expected_targets = self.H.get_neighbor_nodes(source) + actual_targets = self.G_embedding_view.get_neighbor_nodes(source) + if actual_targets != expected_targets: return False return True def get_playground(self): return deepcopy(self) - def get_embedding(self): - return self.G_embedding.get_embedding() + def get_embedding(self, G_to_H_mapping=True): + nodes, edges = self.G_embedding.get_embedding() + if G_to_H_mapping: + mapping = self.get_mapping_G_to_H() + else: + mapping = self.get_mapping_H_to_G() + return nodes, edges, mapping def get_mapping_H_to_G(self): return self.mapping.get_mapping_H_to_G() @@ -123,45 +153,213 @@ def get_mapping_H_to_G(self): def get_mapping_G_to_H(self): return self.mapping.get_mapping_G_to_H() - def try_to_add_missing_edges(self) -> int: + def get_nodes_G(self, node_H: int) -> set[int]: + return self.mapping.get_nodes_G(node_H) + + def get_nodes_H(self) -> set[int]: + return self.H.get_nodes() + + def get_supernode_degree_percentages(self) -> dict[int, float]: + """Returns a dictionary of percentages for each supernode indicating + how many edges between supernodes are currently embedded in G compared + to how many should be as specified in the input graph H.""" + degree_percentages = {} + for source_H in self.H.get_nodes(): + expected_degree = len(self.H.get_neighbor_nodes(source_H)) + actual_degree = len(self.G_embedding_view.get_neighbor_nodes(source_H)) + degree_percentages[source_H] = min(1.0, actual_degree / expected_degree) + return degree_percentages + + def _get_supernode_sizes(self) -> dict[int, int]: + supernode_sizes = {} + for source_H in self.H.get_nodes(): + supernode_nodes = self.get_nodes_in_supernode(source_H) + supernode_sizes[source_H] = len(supernode_nodes) + return supernode_sizes + + def get_sorted_supernodes_by_size(self) -> list[int]: + """Returns a list of sorted supernode keys according to their size + (how many nodes in the hardware graph they map onto). """ - Tries to add missing edges if possible. + supernode_sizes = self._get_supernode_sizes() + # sort according to value (supernode size) + sorted_entries = sorted(supernode_sizes.items(), key=lambda item: item[1]) + return [entry[0] for entry in sorted_entries] + + def try_embed_missing_edges(self) -> int: + """Tries to embed missing edges if possible. - Returns - ------- - How many missing edges were successfully added. + Returns: + int: How many missing edges were successfully added. """ - missing_edges_added = 0 - - for frm in self.H._get_nodes(): - expected_tos = self.H._get_neighbor_nodes(frm) - actual_tos = self.G_embedding_view.get_neighbor_nodes(frm) - # actual_tos = [self.G_embedding_view.get_neighbor_nodes(frm) - # for frm in self.mapping.get_node_G(node_H=frm)] - # actual_tos = list(itertools.chain(*actual_tos)) # flatten - - for to in expected_tos: - if to not in actual_tos: - # print(f'missing edge from H: {frm}-{to}') - # Can we add this edge with the current embedding? - possible_edges = list(itertools.product( - self.mapping.get_node_G(node_H=frm), self.mapping.get_node_G(node_H=to))) - # product since we are dealing with possible chains + missing_edges_added = set() + + for source_H in self.H.get_nodes(): + expected_targets = self.H.get_neighbor_nodes(source_H) + actual_targets = self.G_embedding_view.get_neighbor_nodes(source_H) + for target_H in expected_targets: + if target_H not in actual_targets: + # All possible combination (accounting for supernodes) + source_supernode_nodes = self.get_nodes_in_supernode(source_H) + target_supernode_nodes = self.get_nodes_in_supernode(target_H) + possible_edges = itertools.product( + source_supernode_nodes, target_supernode_nodes) + + # Can we add missing edge with the current embedding? for possible_edge in possible_edges: - if self.G_layout.exists_edge(possible_edge[0], possible_edge[1]): + try: self.embed_edge(possible_edge[0], possible_edge[1]) - print(f'added missing edge from H: {frm}-{to}') - missing_edges_added += 1 + # logger.info( + # f'➕ Added missing edge in H: {source_H}-{target_H}') + missing_edges_added.add((source_H, target_H)) break # successfully added missing edge + except: + pass # it's ok if we found no possible edge + + # Log + logger.info('Try to add missing edges') + for edge in missing_edges_added: + logger.info(f'➕ Added missing edge in H: {edge[0]}-{edge[1]}') + + return len(missing_edges_added) + + def remove_redundancy(self) -> None: + self.remove_redundant_supernode_nodes() + self.remove_unnecessary_edges_between_supernodes() + + def remove_unnecessary_edges_between_supernodes(self) -> None: + """Tries to remove unnecessary edges, e.g. multiple edges between + two supernodes. + """ + logger.info('Remove unnecessary edges between supernodes') + # For every supernode (chain) + for supernode in self.H.get_nodes(): + considered_supernodes = [] + + # For every node in supernode (chain) + for node in self.get_nodes_in_supernode(supernode): + + # Go through every edge to a neighbor + # that is in ANOTHER supernode + for neighbor in self.get_embedded_neighbors(node): + neighbor_supernode = self.get_supernode(neighbor) + + # Do not consider edges inside of supernodes + if supernode == neighbor_supernode: + continue + + # Only keep the edge if we didn't have any connection + # to neighbor's supernode yet + if neighbor_supernode not in considered_supernodes: + considered_supernodes.append(neighbor_supernode) + else: + self.G_embedding.remove_edge(node, neighbor) + # No need adjust G_embedding_view as + # this must be preserved by this method + + def remove_redundant_supernode_nodes(self): + logger.info('Removing redundant supernode nodes') + for supernode in self.H.get_nodes(): + self.remove_redundant_nodes_in_supernode(supernode) + + def remove_redundant_nodes_in_supernode(self, supernode) -> None: + supernode_nodes = self.get_nodes_in_supernode(supernode) + + if len(supernode_nodes) == 1: + return + + removed_nodes = set() + while True: + removed_in_this_iteration = False + + # Calculate articulation points + # We need to recalculate them every time a node was removed + # since the articulation points might change in this case + articulation_points = ArticulationPointCalculator(self.G_embedding)\ + .calc_articulation_points(supernode_nodes - removed_nodes) + logger.info(f'supernode {supernode} (nodes: {supernode_nodes}) ' + + f'has articulation points: {articulation_points}') + + # Try to remove ONE node in the supernode + for node_to_remove in supernode_nodes: + if node_to_remove in removed_nodes: + continue + + # Don't remove articulation points (aka "cut nodes") + if node_to_remove in articulation_points: + continue + + # Can we reach all previous neighbors of supernode? + node_to_remove_neighbors = self.get_embedded_neighbors(node_to_remove) + if node_to_remove_neighbors: + rest_nodes_reachable = [self.get_embedded_neighbors(node) + for node in supernode_nodes + if node != node_to_remove] + rest_nodes_reachable = itertools.chain(*rest_nodes_reachable) + + if not all([neighbor in rest_nodes_reachable + for neighbor in node_to_remove_neighbors + # chain connectivity already ensured + if neighbor not in supernode_nodes]): + continue + + # We can now safely remove the node + self.remove_node(node_to_remove) + removed_in_this_iteration = True + removed_nodes.add(node_to_remove) + logger.info(f'✂ Removed node: {node_to_remove}') + + # Leave at least one node left of every supernode + if len(removed_nodes) == (len(supernode_nodes) - 1): + return + + break + + if not removed_in_this_iteration: + return + + def remove_node(self, node: int) -> None: + # Embedding + self.G_embedding.remove_node(node) + + # Mapping + supernode = self.get_supernode(node) + self.mapping.remove_mapping(supernode, node) + + def check_supernode_connectiveness(self, supernode: int) -> bool: + """Checks that no supernodes are split up into multiple groups + by the mutation. All nodes in a supernode must have an edge to at least + one other supernode. + """ + supernode_nodes = self.get_nodes_in_supernode(supernode) + for node in supernode_nodes: + embedded_neighbors = self.get_embedded_neighbors(node) + + reached = False + for neighbor in embedded_neighbors: + neighbor_supernode = self.get_supernode(neighbor) + if neighbor_supernode == supernode: + reached = True - return missing_edges_added + if not reached: + return False + + return True ############################### Exceptions ##################################### class NoFreeNeighborNodes(Exception): - def __init__(self, from_node): - self.from_node = from_node + def __init__(self, source): + self.source = source + + def __str__(self): + return f'Node {self.source} has no free neighbors' + + +class NoViableEdge(Exception): + def __init__(self, node1, node2): + self.edge = (node1, node2) def __str__(self): - return f'NoFreeNeighborNodes from node: {self.from_node}' + return f'Not a valid edge: {self.edge[0]}-{self.edge[1]}' diff --git a/python/src/embedding/graph_mapping.py b/python/src/embedding/graph_mapping.py index edaa9d7..1e47597 100644 --- a/python/src/embedding/graph_mapping.py +++ b/python/src/embedding/graph_mapping.py @@ -1,26 +1,32 @@ +from typing import Optional + + class GraphMapping(): """ Invertable unique dict using sets as values to encode the mapping between - the small view of a graph and the big view. + nodes in the input graph H to embed into the hardware graph G. """ - def __init__(self): + def __init__(self, size_H: int): self.H_to_G = dict() # values are ints self.G_to_H = dict() # values are sets + self.max_supernodes_count = size_H - def get_node_G(self, node_H): - # we explicitly do NOT handle KeyErrors here as they should never happen - return self.H_to_G[node_H] + def get_nodes_G(self, node_H: int) -> set[int]: + # Note that we do not handle KeyErrors here as they should never occur + # Might want to use method: get_supernode_create_if_not_available() + return self.H_to_G[node_H].copy() - def get_node_H(self, node_G): - # we explicitly do NOT handle KeyErrors here as they should never happen + def get_node_H(self, node_G: int) -> int: + # Note that we do not handle KeyErrors here as they should never occur return self.G_to_H[node_G] - def __set_mapping(self, node_H: int, node_G: int): + def set_mapping(self, node_H: int, node_G: int): self.H_to_G[node_H] = set([node_G]) self.G_to_H[node_G] = node_H def extend_mapping(self, node_H: int, node_G: int): + """Places ``node_G`` into the super node representing ``node_H``.""" try: self.H_to_G[node_H].add(node_G) except KeyError: @@ -28,22 +34,32 @@ def extend_mapping(self, node_H: int, node_G: int): self.G_to_H[node_G] = node_H def remove_mapping(self, node_H: int, node_G: int): + """Removes ``node_G`` from the super node represents ``node_H``.""" self.H_to_G[node_H].remove(node_G) del self.G_to_H[node_G] - def add_mapping_new_node_H(self, node_G: int): - # Check if there exists already a mapping + def get_supernode_create_if_not_available(self, node_G: int) -> int: + """Returns the supernode for ``node_G``. + + If there is no supernode of ``node_G``, create a new supernode and return it. + """ try: - node_H = self.G_to_H[node_G] - return node_H + supernode = self.G_to_H[node_G] except KeyError: - # Make new mapping to new node - node_H = len(self.H_to_G.keys()) - self.__set_mapping(node_H, node_G) - return node_H + supernode = self._get_new_supernode() + self.set_mapping(supernode, node_G) + + return supernode + + def _get_new_supernode(self) -> int: + supernode = len(self.H_to_G.keys()) + if supernode >= self.max_supernodes_count: + raise KeyError(f'Maximum of possible embeddings reached: ' + f'{self.max_supernodes_count}') + return supernode def get_mapping_H_to_G(self): - return self.H_to_G - + return self.H_to_G.copy() + def get_mapping_G_to_H(self): - return self.G_to_H + return self.G_to_H.copy() diff --git a/python/src/graph/__init__.py b/python/src/graph/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/python/src/graph/chimera_graph.py b/python/src/graph/chimera_graph.py new file mode 100644 index 0000000..d2c3a8a --- /dev/null +++ b/python/src/graph/chimera_graph.py @@ -0,0 +1,96 @@ +import dwave_networkx as dnx +from src.graph.undirected_graph import UndirectedGraphAdjList + + +class ChimeraGraphLayout(UndirectedGraphAdjList): + + def __init__(self, m: int, n: int, t=4): + """Creates a Chimera lattice of size (m, n, t). + + Args: + m (int): Number of rows in the Chimera lattice. + n (int, optional, default m): Number of columns in the Chimera lattice. + t (int, optional, default 4): Size of the shore within each Chimera tile. + + Returns: + G : NetworkX Graph + An (m, n, t) Chimera lattice. Nodes are labeled by integers. + + A Chimera lattice is an m-by-n grid of Chimera tiles. Each Chimera + tile is itself a bipartite graph with shores of size t. The + connection in a Chimera lattice can be expressed using a node-indexing + notation (i,j,u,k) for each node. + + * (i,j) indexes the (row, column) of the Chimera tile. i must be + between 0 and m-1, inclusive, and j must be between 0 and + n-1, inclusive. + * u=0 indicates the left-hand nodes in the tile, and u=1 indicates + the right-hand nodes. + * k=0,1,...,t-1 indexes nodes within either the left- or + right-hand shores of a tile. + + In this notation, two nodes (i, j, u, k) and (i', j', u', k') are + neighbors if and only if: + + (i = i' AND j = j' AND u != u') OR + (i = i' +/- 1 AND j = j' AND u = 0 AND u' = 0 AND k = k') OR + (i = i' AND j = j' +/- 1 AND u = 1 AND u' = 1 AND k = k') + + The first of the three terms of the disjunction gives the + bipartite connections within the tile. The second and third terms + give the vertical and horizontal connections between blocks + respectively. + + (Partially copied from the official dwave_networkx documentation.) + """ + + # --- Nodes + nodes_count = m * n * 2 * t + self.nodes_count = nodes_count + super().__init__(nodes_count) + + # --- Edges + G = dnx.chimera_graph(m, n, t) + for e in G.edges: + self.set_edge(e[0], e[1]) + + def get_size(self) -> int: + return self.nodes_count + + # def __init__(self, grid_width=1): + # # --- Nodes + # # One chimera cell has 8 nodes + # nodes_count = 8 * grid_width**2 + # super().__init__(nodes_count) + + # # --- Edges + # # Start from top-left corner to top-right + # # then go bottom + # cell_start_offset = 0 + + # for i in range(grid_width): + # for j in range(grid_width): + + # # --- One Chimera cell + # for chimera_i in range(0, 4): + # for chimera_j in range(4, 8): + # self.set_edge(chimera_i + cell_start_offset, + # chimera_j + cell_start_offset) + + # # --- Edges to other cells + + # # 0,1,2,3 to bottom cell + # # Check that we are not one of most bottom cells + # if i != grid_width - 1: + # for chimera_i in range(0, 4): + # self.set_edge(chimera_i + grid_width, + # chimera_i + grid_width + (grid_width*8)) + + # # 4,5,6,7 to right-hand cell + # # Check that we are not one of most right-hand cells + # if j != grid_width - 1: + # for chimera_j in range(4, 8): + # self.set_edge(chimera_j + cell_start_offset, + # chimera_j + cell_start_offset + 8) + + # cell_start_offset += 8 diff --git a/python/src/graph/embedding_graph.py b/python/src/graph/embedding_graph.py new file mode 100644 index 0000000..0d5ea52 --- /dev/null +++ b/python/src/graph/embedding_graph.py @@ -0,0 +1,80 @@ +from src.graph.undirected_graph import UndirectedGraphAdjList + + +class EmbeddingGraph(UndirectedGraphAdjList): + """A Graph to **form** an embedding (using an adjacency list). + + This Graph is supposed to **converge into a valid minor** of another graph + by using the methods it provides, e.g. to embed edges, form chains etc. + + Hint: + Pay attention whether you use methods which are directly defined here + or in the parent class + :py:class:`src.graph.undirected_graph.UndirectedGraphAdjList`. + Methods defined over there may not be convenient as the current class + tries to hide implementation details, e.g. chains being encoded as + edge costs. It is recommend to just stick to the methods defined here + (in the subclass). + + Warning: + This class does not implement any checks for chains, so it is possible + to assign a node to multiple chains. + """ + + def __init__(self, nodes_count): + self._chain_last = 0 + super().__init__(nodes_count) + + ############################### Edges ###################################### + + def embed_edge(self, frm: int, to: int) -> None: + """Embeds an edge (and optionally assigns a chain). + + Args: + frm (int): One node of the edge. + to (int): The other node of the edge. + chain (int, optional): The chain to assign to the new embedded edge. \ + The default value `0` means: no chain, just a "normal" edge. + + Raises: + GraphNodeIndexError: If the given node ``frm`` or ``to`` \ + does not exist in the Graph. + """ + super().set_edge(frm, to, cost=0) + + def get_embedded_edges(self) -> set[tuple[int, int, int]]: + """Returns all embedded edges. + + Returns: + set[tuple[int, int, int]]: A set of entries (frm, to, cost) \ + describing all embedded edges of this Graph with their \ + respective costs. + """ + return super().get_edges() + + ################################# Nodes #################################### + + def get_embedded_nodes(self) -> set[int]: + """Returns all embedded nodes. + + Returns: + set[int]: The embedded nodes. + """ + nodes = super().get_nodes() + nodes = {node for node in nodes if self.get_neighbor_nodes(node)} + return nodes + + ############################### Embedding ################################## + + def get_embedding(self) -> tuple[set[int], set[tuple[int, int, int]]]: + """Returns the current embedding. + + Returns: + tuple[list[int], list[tuple[int, int, int]]]: \ + A tuple of nodes and edges. `nodes` is a list of integers, \ + while `edges` is a list of tuples (frm, to, chain) describing \ + the edges (frm node, to node, chain) + """ + nodes = self.get_embedded_nodes() + edges = self.get_embedded_edges() + return nodes, edges diff --git a/python/src/graph/test_graph.py b/python/src/graph/test_graph.py new file mode 100644 index 0000000..7200377 --- /dev/null +++ b/python/src/graph/test_graph.py @@ -0,0 +1,66 @@ +import networkx as nx +from src.graph.undirected_graph import UndirectedGraphAdjList + + +class TestGraph(): + + @staticmethod + def house() -> UndirectedGraphAdjList: + H = UndirectedGraphAdjList(5) + H.set_edge(0, 1) + H.set_edge(0, 4) + H.set_edge(1, 2) + H.set_edge(1, 3) + H.set_edge(2, 3) + H.set_edge(3, 4) + return H + + @staticmethod + def i_letter() -> UndirectedGraphAdjList: + H = UndirectedGraphAdjList(6) + H.set_edge(0, 3) + H.set_edge(3, 2) + H.set_edge(3, 5) + H.set_edge(1, 2) + H.set_edge(2, 4) + return H + + @staticmethod + def k(n: int) -> UndirectedGraphAdjList: + G = nx.complete_graph(n) + H = UndirectedGraphAdjList(n) + for e in G.edges: + H.set_edge(e[0], e[1]) + return H + + @staticmethod + def pyramid() -> UndirectedGraphAdjList: + H = UndirectedGraphAdjList(5) + H.set_edge(0, 1) + H.set_edge(0, 2) + H.set_edge(0, 3) + H.set_edge(0, 4) + H.set_edge(1, 2) + H.set_edge(2, 3) + H.set_edge(3, 4) + return H + + @staticmethod + def tree_like() -> UndirectedGraphAdjList: + H = UndirectedGraphAdjList(6) + H.set_edge(0, 1) + H.set_edge(0, 2) + H.set_edge(0, 3) + H.set_edge(1, 4) + H.set_edge(1, 5) + H.set_edge(2, 5) # comment this line out to get a tree + return H + + @staticmethod + def crossed_house() -> UndirectedGraphAdjList: + # In Germany known as "Haus vom Nikolaus" + H = TestGraph.k(4) + new_node = H.add_node() + H.set_edge(1, new_node) + H.set_edge(2, new_node) + return H diff --git a/python/src/graph/undirected_graph.py b/python/src/graph/undirected_graph.py new file mode 100644 index 0000000..e9d5818 --- /dev/null +++ b/python/src/graph/undirected_graph.py @@ -0,0 +1,280 @@ +class UndirectedGraphAdjList: + """ + Undirected Graph using an adjacency list. + """ + + def __init__(self, nodes_count: int): + """Initializes a new Graph. + + Args: + nodes_count (int): The number of nodes this Graph \ + has initially. + """ + self._adj_list: dict[int, AdjListEntryWithCosts] = dict() + self.current_index = -1 + self.nodes_count = 0 # gets incremented in for loop + for _ in range(nodes_count): + self.add_node() + + def _validate_index(self, index: int): + """Checks if the given index is valid for the current Graph.""" + try: + self._adj_list[index] + except KeyError: + raise GraphNodeIndexError(index) + + ############################### Edges ###################################### + + def get_edges(self) -> set[tuple[int, int, int]]: + """Returns all edges of this Graph. + + Returns: + set[tuple[int, int, int]]: A set of entries (frm, to, cost) \ + describing all edges of this Graph with their respective costs. + """ + edges = set() + for frm in self._adj_list.keys(): + for (to, cost) in self._adj_list[frm].get_neighbors_with_costs(): + # frm, to = to, frm + # would be fatal here inside the loop (!) + if frm < to: + edges.add((frm, to, cost)) + else: + edges.add((to, frm, cost)) + return set(edges) + + def exists_edge(self, frm: int, to: int) -> bool: + """Checks if an edge between two nodes exists. + + Args: + frm (int): One node of the edge. + to (int): The other node of the edge. + + Returns: + bool: True if the edge exists. + + Raises: + GraphNodeIndexError: If the given node ``frm`` or ``to`` \ + does not exist in the Graph. + """ + self._validate_index(frm) + self._validate_index(to) + return to in self.get_neighbor_nodes(frm) + + def set_edge(self, frm: int, to: int, cost=0) -> None: + """Sets an edge between nodes ``frm`` and ``to`` and assigns + the given ``cost``. + + Warning: + This may override an existing edge with new costs. + + Args: + frm (int): One node of the edge. + to (int): The other node of the edge. + cost (int): The costs for the edge + + Raises: + GraphNodeIndexError: If the given node ``frm`` or ``to`` \ + does not exist in the Graph. + """ + self._validate_index(frm) + self._validate_index(to) + + self._adj_list[frm].set_edge_to(to, cost) + self._adj_list[to].set_edge_to(frm, cost) # undirected graph + + def remove_edge(self, frm: int, to: int) -> None: + """Removes the edge (if present) between nodes ``frm`` and ``to``. + + Args: + frm (int): One node of the edge. + to (int): The other node of the edge. + + Raises: + GraphNodeIndexError: If the given node ``frm`` or ``to`` \ + does not exist in the Graph. + """ + self._validate_index(frm) + self._validate_index(to) + + self._adj_list[frm].remove_edge_to(to) + self._adj_list[to].remove_edge_to(frm) # undirected graph + + def remove_all_edges_from_node(self, frm: int) -> None: + """Removes all edges connected to the given node. + + Args: + frm (int): node from which all edges should be removed. + + Raises: + GraphNodeIndexError: If the given node ``frm`` \ + does not exist in the Graph. + """ + self._validate_index(frm) + + tos = self._adj_list[frm].get_neighbors() + if not tos: + return # nothing to delete + + for to in tos: + # Delete outgoing edges (by resetting) + self._adj_list[frm].remove_edge_to(to) + + # Delete incoming edges + self._adj_list[to].remove_edge_to(frm) + + ################################# Nodes #################################### + + def get_nodes(self) -> set[int]: + """Returns all nodes of this Graph. + + Returns: + set[int]: All nodes of this Graph. + """ + return set(self._adj_list.keys()) + + def add_node(self) -> int: + """Adds a new node to this Graph. + + Returns: + int: The new node number. + """ + self.nodes_count += 1 + self._adj_list[self.nodes_count-1] = AdjListEntryWithCosts() + return self.nodes_count-1 + + def remove_node(self, node: int) -> None: + self.remove_all_edges_from_node(node) + + # We don't delete the key completely as we use the following encoding: + # Nodes are only embedded nodes later if they have neighbors + # del self._adj_list[node] + + def get_neighbor_nodes(self, source: int) -> set[int]: + """Returns all neighboring nodes. + + Neighboring nodes are nodes that are connected via an edge to this node. + + Args: + source (int): Node from which the neighboring nodes should be retrieved. + + Return: + set[int]: Set of integers describing the neighboring nodes. + + Raises: + GraphNodeIndexError: If the given node ``source`` \ + does not exist in the Graph. + """ + self._validate_index(source) + return self._adj_list[source].get_neighbors() + + def get_neighbor_nodes_with_costs(self, frm: int) -> list[tuple[int, int]]: + """Returns all neighboring nodes with costs. + + Neighboring nodes are nodes that are connected via an edge to this node. + + Args: + frm (int): Node from which the neighboring nodes \ + should be retrieved. + + Return: + list[tuple[int, int]]: List of tuples (to, cost) \ + describing edges with costs. + + Raises: + GraphNodeIndexError: If the given node ``frm`` \ + does not exist in the Graph. + """ + self._validate_index(frm) + return self._adj_list[frm].get_neighbors_with_costs() + + def has_neighbor_nodes(self, frm: int) -> bool: + """Checks if the given node has neighboring nodes. + + Neighboring nodes are nodes that are connected via an edge to this node. + + Args: + frm (int): Node from which the neighboring nodes should be retrieved. + + Returns: + bool: True if the given node has neighboring nodes. + + Raises: + GraphNodeIndexError: If the given node ``frm`` \ + does not exist in the Graph. + """ + return len(self.get_neighbor_nodes(frm)) > 0 + + +class GraphNodeIndexError(Exception): + """Error that occurs when accessing a node that does not exist in the Graph. + + Args: + index (int): Invalid node (represented as integer index in the Graph). + """ + + def __init__(self, index: int): + message = f'Node {index} does not exist in the graph' + super().__init__(message) + + +class AdjListEntryWithCosts(): + """One entry of an adjacency list. + + Describes edges to other nodes and assigns costs to these edges. + + Warning: + This AdjacencyList does *not* check for invalid indexing. + Expect KeyErrors to arise if the caller does not handle indexing correctly. + + Note: + It is guaranteed that an edge from node u to node v cannot exist \ + multiple times with different costs. + """ + + def __init__(self): + self._to_nodes = set() + self._costs = dict() + + ############################### Edges ###################################### + + def set_edge_to(self, to: int, cost: int) -> None: + """Sets an undirected edge with cost to a node. + + Warning: + This may override an existing edge with new costs. + + Args: + to (int): Other node to specify the edge. + cost (int): Cost for the edge + """ + self._to_nodes.add(to) + self._costs[to] = cost # may alter the costs for an existing edge + + def remove_edge_to(self, to: int) -> None: + """Removes an edge to a node. + + Args: + to (int): Other node to specify the edge that should be removed. + """ + self._to_nodes.remove(to) + del self._costs[to] + + ################################# Nodes #################################### + + def get_neighbors(self) -> set[int]: + """Returns all neighboring nodes. + + Returns: + set[int]: All neighboring nodes (from the current node). + """ + return self._to_nodes.copy() + + def get_neighbors_with_costs(self) -> list[tuple[int, int]]: + """Returns all neighboring nodes with costs (from the current node). + + Returns: + list[tuple[int, int]]: All neighboring nodes (from the \ + current node) with costs. + """ + return [(to, self._costs[to]) for to in self._to_nodes] diff --git a/python/src/graphs/chimera_graph.py b/python/src/graphs/chimera_graph.py deleted file mode 100644 index 22b22a2..0000000 --- a/python/src/graphs/chimera_graph.py +++ /dev/null @@ -1,107 +0,0 @@ -from src.graphs.undirected_graphs import (UndirectedGraphAdjList, - UndirectedGraphAdjMatrix) - -# Chimera graph Graph gird structure (not needed right now) -# 4 -# x x x x ——4 -# 5 x x x x ——5 -# 0 1 2 3 x x x x ——6 -# 6 x x x x ——7 -# | | | | -# 7 0 1 2 3 -# - - -class ChimeraGraphLayout(UndirectedGraphAdjList): - """ - A Chimera graph representation (right now with fixed shore_size of 4 - and a single unit cell TODO). - """ - - def __init__(self): - shore_size = 4 # TODO: init layout of ChimeraGraph dynamically - vertices_count = shore_size * 2 - super().__init__(vertices_count) - - # Define layout of Chimera graphs - for i in range(0, 4): # TODO: use shore_size here - for j in range(4, 8): - self._set_edge(i, j) - - def get_neighbor_nodes(self, from_node): - return super()._get_neighbor_nodes(from_node) - - def exists_edge(self, frm, to): - return to in super()._get_neighbor_nodes(frm) - - -class GraphEmbedding(UndirectedGraphAdjList): - """ - A Graph Embedding - """ - - def __init__(self, nodes_count): - self._chain_last = 0 - super().__init__(nodes_count) - - def get_neighbor_nodes(self, from_node): - return super()._get_neighbor_nodes(from_node) - - def embed_edge(self, frm, to, chain=0): - # Chain=0 means no chain, just a "normal" edge - super()._set_edge(frm, to, cost=chain) - - def get_nodes_in_same_chain(self, node): - chain = self._get_node_chain(node) - if chain == 0: - return node - return self._get_chain_nodes(chain) - - def _get_node_chain(self, node): - edges = super()._get_edges_from_node(node) - if not edges: - return 0 - else: - return edges[0][1] - - def _get_chain_nodes(self, chain): - if chain == 0: - return [] - - nodes = super()._get_nodes() - return [node for node in nodes - if self._get_node_chain(node) == chain] - - def remove_edge(self, frm, to): - super()._remove_edge(frm, to) - - def delete_all_edges_from_node(self, frm): - super()._delete_all_edges_from_node(frm) - - def add_chain(self, node1, node2): - self._chain_last += 1 - self.embed_edge(node1, node2, chain=self._chain_last) - return self._chain_last - - def add_node(self): - super()._add_node() - - def get_embedded_nodes(self): - nodes = super()._get_nodes() - # Filter for nodes that have an edge - nodes = [node for node in nodes if self._adj_list[node].get()] - return nodes - - def get_free_nodes(self): - nodes = super()._get_nodes() - # Filter for nodes that don't have an edge - nodes = [node for node in nodes if not self._has_node_edges(node)] - return nodes - - def get_embedded_edges(self): - return super()._get_edges() - - def get_embedding(self): - nodes = self.get_embedded_nodes() - edges = self.get_embedded_edges() - return nodes, edges diff --git a/python/src/graphs/undirected_graphs.py b/python/src/graphs/undirected_graphs.py deleted file mode 100644 index 8d24b82..0000000 --- a/python/src/graphs/undirected_graphs.py +++ /dev/null @@ -1,132 +0,0 @@ -class UndirectedGraphAdjMatrix: - """ - An undirected Graph representation using an adjacency MATRIX with costs. - The number of graph vertices is fixed after initialization. - - - `-1` in the adjacency matrix means: no edge - - `0` in the adjacency matrix means: edge with cost 0 (default for cost) - """ - - def __init__(self, vertices_count): - self.vertices_count = vertices_count - self._adj_matrix = [[-1]*vertices_count for x in range(vertices_count)] - - def _set_edge(self, frm, to, cost=0): - self._adj_matrix[frm][to] = cost - # set vice-versa to preserve symmetric matrix (undirected graph) - self._adj_matrix[to][frm] = cost - - def _get_edge_cost(self, frm, to): - return self._adj_matrix[frm][to] - - def _get_edges(self): - edges = [] - for i in range(self.vertices_count): - for j in range(self.vertices_count): - if (self._adj_matrix[i][j] != -1): - edges.append((i, j, self._adj_matrix[i][j])) - return edges - - def _get_adj_matrix(self): - return self._adj_matrix - - -class UndirectedGraphAdjList: - """ - An undirected Graph representation using an adjacency LIST without costs. - The number of graph vertices is fixed after initialization. - - This class may be primarily used for O(1) search for whether there is - an edge from vertex u to vertex v. - """ - - def __init__(self, nodes_count): - self.nodes_count = nodes_count - self._adj_list = dict() - for i in range(nodes_count): - self._adj_list[i] = AdjListEntryWithCosts() - - def _set_edge(self, frm, to, cost=0): - try: - self._adj_list[frm].add(to, cost) - # set vice-versa to preserve symmetric matrix (undirected graph) - self._adj_list[to].add(frm, cost) - except: - raise IndexError( - f'Graph only contains {self.nodes_count} vertices') - - def _remove_edge(self, frm, to): - self._adj_list[frm].remove(to) - self._adj_list[to].remove(frm) - - def _delete_all_edges_from_node(self, frm): - tos = self._adj_list[frm].get_to_nodes() - if not tos: - return - - # Delete all outgoing edges - self._adj_list[frm] = AdjListEntryWithCosts() - - # Delete specific incoming edges - for to in tos: - self._adj_list[to].remove(frm) - - def _get_edges_from_node(self, from_node): - try: - return self._adj_list[from_node].get() - except: - raise IndexError( - f'Graph only contains {self.nodes_count} vertices') - - def _get_neighbor_nodes(self, from_node): - neighbors = self._get_edges_from_node(from_node) - # We only need the neighbor nodes, no costs - neighbors = [neighbor[0] for neighbor in neighbors] - return neighbors - - def _has_node_edges(self, node): - return len(self._adj_list[node].get()) > 0 - - def _get_nodes(self): - return self._adj_list.keys() - - def _add_node(self): - self.nodes_count += 1 - self._adj_list[self.nodes_count-1] = AdjListEntryWithCosts() - - def _get_edges(self): - edges = set() - for frm in self._adj_list.keys(): - for (to, cost) in self._adj_list[frm].get(): - # frm, to = to, frm - # would be fatal here inside the loop (!) - if frm < to: - edges.add((frm, to, cost)) - else: - edges.add((to, frm, cost)) - return edges - - -class AdjListEntryWithCosts(): - """ - One entry of an adjacency list. Allows for costs. Makes sure that an edge - from node u to node v cannot exist multiple times with different costs. - """ - - def __init__(self): - self.to_nodes = set() - self.costs = dict() - - def add(self, to, cost): - self.to_nodes.add(to) - self.costs[to] = cost # may alter the costs for an existing edge - - def remove(self, to): - self.to_nodes.remove(to) - del self.costs[to] - - def get_to_nodes(self): - return self.to_nodes - - def get(self): - return [(to, self.costs[to]) for to in self.to_nodes] diff --git a/python/src/results/chances.txt b/python/src/results/chances.txt new file mode 100644 index 0000000..4baab79 --- /dev/null +++ b/python/src/results/chances.txt @@ -0,0 +1,2 @@ +[0.5 0. 0. 0. 0. 0.5 0. 0. 0. 0. 0. 0. ] +[0.06 0.01 0.1 0.07 0. 0.08 0.13 0.16 0.15 0.03 0.12 0.09] \ No newline at end of file diff --git a/python/src/results/degree_percentage.py b/python/src/results/degree_percentage.py new file mode 100644 index 0000000..74d1f12 --- /dev/null +++ b/python/src/results/degree_percentage.py @@ -0,0 +1,113 @@ +import csv + +import matplotlib.pyplot as plt +import matplotlib.ticker as ticker +from src.drawing.node_colors import get_supernode_color +from src.embedding.embedding import Embedding + +# Matplotlib +# https://stackoverflow.com/a/7389998 +# https://stackoverflow.com/a/10944967 +plt.ion() +plt.rcParams.update({ + 'axes.titlesize': 22, + 'text.usetex': True, + 'font.family': 'Helvetica' +}) + +# https://stackoverflow.com/a/39566040/9655481 +MEDIUM_SIZE = 8 +MEDIUM_SIZE = 14 +BIGGER_SIZE = 16 + +plt.rc('font', size=MEDIUM_SIZE) # controls default text sizes +plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title +plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels +plt.rc('xtick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('ytick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('legend', fontsize=MEDIUM_SIZE) # legend fontsize +plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + +class DegreePercentageData(): + + x_generation_data = [] + y_percentage_datas = [] + lines = [] + DP_FILE_PATH = './out/dp.csv' + + def __init__(self, max_nodes) -> None: + self.max_nodes = max_nodes + self._setup_plot() + + def save_current_degree_percentages(self, generation, embedding: Embedding): + degree_percentages = embedding.get_supernode_degree_percentages() + values = [round(value, 2) for value in degree_percentages.values()] + self._update_plot(generation, values) + + # Append to file + with open(self.DP_FILE_PATH, 'a', newline='') as f: + writer = csv.writer(f) + row = [generation] + values + writer.writerow(row) + + def _setup_plot(self): + self.figure, self.ax = plt.subplots() + + # Prepare 2D lines + for i in range(self.max_nodes): + self.y_percentage_datas.append([]) + + # Style plot + # https://stackoverflow.com/a/55762294/9655481 + #linewidth = 5 - 3 * (i / self.max_nodes) + #linestyle = ['-', '--', '-.', ':'][i % 4] + color = get_supernode_color(i) + + line, = self.ax.plot([], [], color=color, marker='o', markersize=5, + label=i, linewidth=1.8) + self.lines.append(line) + + plt.xlabel('Generation') + plt.ylabel('Super vertices degree percentages') + plt.legend() + + # Autoscale on unknown axis and known lims on the other + self.ax.set_autoscaley_on(True) + self.ax.set_ylim(0.0, 1.1) + self.ax.xaxis.set_major_locator(ticker.MultipleLocator(1)) + # self.ax.set_xlim(0, 100) + + self.ax.grid() + + plt.tight_layout() + plt.show(block=False) + + def _update_plot(self, generation, values): + # https://stackoverflow.com/a/24272092 + + # Set new data + self.x_generation_data.append(generation) + for i, v in enumerate(values): + # Avoid overlapping lines by shifting them a tiny bit + prior_values = values[:i] + count_v = prior_values.count(v) + if count_v: + v += 0.010 * count_v + self.y_percentage_datas[i].append(v) + + # Update data (with the new *and* the old points) + for i, line in enumerate(self.lines): + line.set_xdata(self.x_generation_data) + line.set_ydata(self.y_percentage_datas[i]) + + # Need both of these in order to rescale + self.ax.relim() + self.ax.autoscale_view() + + # We need to draw *and* flush + self.figure.canvas.draw() + self.figure.canvas.flush_events() + + def plot_blocking(self): + plt.show(block=True) diff --git a/python/src/results/selection_chances.py b/python/src/results/selection_chances.py new file mode 100644 index 0000000..06ec52a --- /dev/null +++ b/python/src/results/selection_chances.py @@ -0,0 +1,59 @@ +import matplotlib.pyplot as plt +import numpy as np + +with open('./chances.txt', 'r') as f: + line1 = f.readline() + line2 = f.readline() + p1 = np.fromstring(line1[1:-1], sep=' ') + p2 = np.fromstring(line2[1:-1], sep=' ') + x = np.arange(len(p1)) + +# --- Plot setup +plt.rcParams.update({ + "text.usetex": True, + "font.family": "Helvetica" +}) + +# https://stackoverflow.com/a/39566040/9655481 +MEDIUM_SIZE = 8 +MEDIUM_SIZE = 18 +BIGGER_SIZE = 20 + +plt.rc('font', size=MEDIUM_SIZE) # controls default text sizes +plt.rc('axes', titlesize=MEDIUM_SIZE) # fontsize of the axes title +plt.rc('axes', labelsize=MEDIUM_SIZE) # fontsize of the x and y labels +plt.rc('xtick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('ytick', labelsize=MEDIUM_SIZE) # fontsize of the tick labels +plt.rc('legend', fontsize=MEDIUM_SIZE) # legend fontsize +plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title + + +width = 0.35 # the width of the bars +fig, ax = plt.subplots(figsize=(14, 11)) +color_blue = '#2981B3' +color_red = '#E53054' +rects1 = ax.bar(x - width/2, p1, width, label='without increase', color=color_blue) +rects2 = ax.bar(x + width/2, p2, width, + label='with increase for small super vertices', color=color_red) + +# ax.set_xticks(x, x) +ax.legend() +ax.set_ylim(0, 0.5) + +ax.bar_label(rects1, padding=3) +ax.bar_label(rects2, padding=3) +# fig.tight_layout() +plt.xlabel('Super vertex') +plt.ylabel('Chance of selecting the super vertex') +# plt.title('Selection chances') +plt.tight_layout() +plt.show() + +# plt.ylim(0, 0.2) +# plt.plot(x, p1, marker='o', linestyle='--', label='without increase') +# plt.plot(x, p2, marker='o', linestyle='--', label='with increase for small supernodes') +# plt.xlabel('Supernodes') +# plt.ylabel('Chance of selecting a supernode') +# plt.title('Selection chances') +# plt.legend() +# plt.show() diff --git a/python/src/solver/embedding_solver.py b/python/src/solver/embedding_solver.py index cdeb4c8..1790bdc 100644 --- a/python/src/solver/embedding_solver.py +++ b/python/src/solver/embedding_solver.py @@ -1,128 +1,118 @@ +import logging import random +from dataclasses import dataclass +from typing import Optional from src.embedding.embedding import Embedding -from src.graphs.undirected_graphs import UndirectedGraphAdjList +from src.graph.undirected_graph import UndirectedGraphAdjList +from src.solver.initialization import Initialization +from src.solver.supernode_extension import SupernodeExtension + +logger = logging.getLogger('evolution') + + +@dataclass +class EvolutionParams(): + population_size: int + max_mutation_trials: int + mutation_extend_to_free_neighbors_probability: float class EmbeddingSolver(): - def __init__(self, H: UndirectedGraphAdjList): + def __init__(self, H: UndirectedGraphAdjList, m, n, t): self.H = H if H.nodes_count < 2: raise NameError('The minor to embed must have at least two nodes') - self.embedding = Embedding(H) - - def init_basic_path(self) -> None: - """Inits the graph as path graph starting from vertex 0 in the Chimera graph. - The length is determined by the number of vertices of the minor to embed. - """ - # Init with path graph as long as H - # TODO: what if no path graph embedding is possible? When is this the case? - # Start at vertex 0 - node_from = 0 - for _ in range(self.H.nodes_count-1): - # Choose random neighbor - neighbors = self.embedding.get_free_neighbors(node_from) - node_to = random.choice(neighbors) - - # Embed - self.embedding.embed_edge(node_from, node_to) - - node_from = node_to + self._embedding = Embedding(H, m, n, t) + self.initialization = Initialization(self._embedding) + self._supernode_extension = SupernodeExtension(self._embedding) - self.embedding.try_to_add_missing_edges() + def initialize_embedding(self): + self.initialization.init_dfs() + self._local_maximum() def get_embedding(self): - return self.embedding.get_embedding() - - def _add_random_chain(self): - # --- Randomly collapse two nodes to one - nodes_embedded = self.embedding.get_embedded_nodes() - # TODO: make sure we don't use nodes that are already in a chain - from_node = random.choice(nodes_embedded) - node_tos = self.embedding.get_connected_neighbors(from_node) - to_node = random.choice(node_tos) - print(f'Trying to chain nodes {from_node} and {to_node}') - - # --- Adjust so that new chain is viable - # find new place for previous node_to in the graph - # so that the layout permits the following edges - # node_to --- node_to' - # node_to' --- all_nodes reachable from node_to - to_node_free_neighbors = self.embedding.get_free_neighbors(to_node) - to_node_connected_neighbors = self.embedding.get_connected_neighbors( - to_node) - - # --- 1) Try out all possible positions for node_to_new - for to_node_new in to_node_free_neighbors: - print(f'node_to_new: {to_node_new}') - - # from node_to_new: can we reach all nodes previously connected to node_to? - node_to_new_reachable_neighbors = self.embedding.get_reachable_neighbors( - to_node_new) - can_reach = [neighbor in node_to_new_reachable_neighbors - for neighbor in to_node_connected_neighbors if neighbor != from_node] - if all(can_reach): - # Try out on playground - playground = self.embedding.get_playground() - playground.add_chain_to_used_nodes( - from_node, to_node, to_node_new) - playground.try_to_add_missing_edges() - return playground - - # --- 2) If step 1) did not work, try to construct another new chain (-> two chains in total) - to_node_new = to_node_free_neighbors[0] - to_node_new_free_neighbors = self.embedding.get_free_neighbors( - to_node_new) - to_node_new_chain_partner = to_node_new_free_neighbors[0] - - # from to_node_new AND to_node_new_chain_partner: - # Can we now reach all nodes previously connected to node_to - chain_reachable_nodes = self.embedding.get_reachable_neighbors( - to_node_new) - chain_reachable_nodes.extend( - self.embedding.get_reachable_neighbors(to_node_new_chain_partner)) - can_reach = [neighbor in chain_reachable_nodes - for neighbor in to_node_connected_neighbors if neighbor != from_node] - if all(can_reach): - # Try out on playground - playground = self.embedding.get_playground() - - playground.extend_one_node_to_chain( - to_node_new, to_node_new_chain_partner, extend_G=to_node) - - # edge to_node---to_node_new - # will be removed when adding this chain: - playground.add_chain_to_used_nodes( - from_node, to_node, to_node_new) - - print( - f'to_node_new to chain partner: {to_node_new}---{to_node_new_chain_partner}') - playground.try_to_add_missing_edges() - return playground - - # 3. If all of that fails, mark the mutation as failed + return self._embedding.get_embedding(G_to_H_mapping=True) + + def commit(self, playground: Embedding): + self._embedding = playground + self._supernode_extension = SupernodeExtension(self._embedding) + + def generate_population_and_select(self, params: EvolutionParams) -> Optional[Embedding]: + """Generates a new population & selects and returns the best individual + from it.""" + population = self._generate_children(params) + if not population: + population = self.last_trial(params) + if not population: + logger.info(f'🔳 Population generation failed') + return None + + if len(population) < params.population_size: + logger.info(f'🔳 {params.max_mutation_trials} mutations to construct ' + ' a new child failed, will return a smaller population: ' + f'{len(population)}/{params.population_size}') + + selected_population = self._select_best_child(population) + return selected_population + + def last_trial(self, params: EvolutionParams) -> Optional[list[Embedding]]: + """Try to remove unnecessary supernode nodes and generate a new population""" + logger.info(f'🔳 Last trial, remove redundant nodes') + self._embedding.remove_redundancy() + return self._generate_children(params) + + def _generate_children(self, params: EvolutionParams) -> list[Embedding]: + """Generates children (Embeddings) for one population.""" + population = [] # list of Embeddings + + for i in range(params.population_size): + child = self._generate_child(params, i) + if child: + population.append(child) + else: + # early return as it is unlikely that we will be able + # to generate more children + return population + + return population + + def _generate_child(self, params: EvolutionParams, child_number: int) -> Optional[Embedding]: + logger.info('') + logger.info(f'--- Try find a new viable mutation') + + for _ in range(params.max_mutation_trials): + logger.info('--- MUTATION') + if random.random() < params.mutation_extend_to_free_neighbors_probability: + mutation = self._supernode_extension.extend_random_supernode_to_free_neighbors() + else: + mutation = self._supernode_extension.extend_random_supernode() + + if mutation: + logger.info(f'💚 Valid mutation for child {child_number}') + return mutation + + logger.info(f'🔳 All {params.max_mutation_trials} mutations failed, ' + 'could not construct a child -> Abort') return None - def mutate(self): - """ - Mutates the embedding. Supports adding random chains rights now. - """ - print('--- MUTATION') - # --- Delete & Insert edge - # Delete an edge between two random nodes that were already embedded. - # Insert a new edge between two other random nodes that were already embedded. + def _select_best_child(self, population: list[Embedding]): + logger.info('') + logger.info('Select best child') - # Add random chain - return self._add_random_chain() + # Try to optimize to local maximum first + improvements = [] + for i, child in enumerate(population): + logger.info(f'💚 Checking local optima for child {i}') + improvements.append(child.try_embed_missing_edges()) - # TODO: Remove chain mutation + best_child_index = improvements.index(max(improvements)) + return population[best_child_index] - # --- Perspective change - # TODO: with low probability: view reduced graph from completely different view - # maybe from this perspective, we can leverage some better mutations - # and reduce the costs faster + def _local_maximum(self) -> int: + return self._embedding.try_embed_missing_edges() def found_embedding(self) -> bool: - return self.embedding.is_valid_embedding() + return self._embedding.is_valid_embedding() diff --git a/python/src/solver/evolution.py b/python/src/solver/evolution.py index fbc9506..6fdc161 100644 --- a/python/src/solver/evolution.py +++ b/python/src/solver/evolution.py @@ -1,58 +1,182 @@ -from src.drawing.draw import Draw -from src.graphs.undirected_graphs import UndirectedGraphAdjList -from src.solver.embedding_solver import EmbeddingSolver - - -def init_H(): - # K4 graph - H = UndirectedGraphAdjList(4) - H._set_edge(0, 1) - H._set_edge(0, 2) - H._set_edge(0, 3) - H._set_edge(1, 2) - H._set_edge(1, 3) - H._set_edge(2, 3) - return H - - -def main(): - print('--- Main ---') - - # --- Setup - d = Draw() - H = init_H() - d.draw_chimera_graph(1, 1, 4) # one unit cell of Chimera graph - - # --- Start solving - solver = EmbeddingSolver(H) - solver.init_basic_path() - found_embedding = solver.found_embedding() - if found_embedding: - print('✨🎉 Found embedding') - return - - # --- Mutation - playground = solver.mutate() - if not playground: - print('Not a viable mutation') - return - - # --- Output - print() - print('--- Output ---') - nodes, edges = playground.get_embedding() - mapping = playground.get_mapping_H_to_G() - - print('*** Final mapping ***') - print(mapping) - print('*** Final embedding ***') - print(nodes) - print(edges) - print(f'Is correct: {playground.is_valid_embedding()}') - - mapping_G_to_H = playground.get_mapping_G_to_H() - d.draw_embedding(nodes, edges, mapping_G_to_H) +import logging +import os +import shutil +import signal +from random import random +from typing import Optional + +from src.drawing.draw import DrawEmbedding +from src.embedding.embedding import Embedding +from src.graph.test_graph import TestGraph +from src.results.degree_percentage import DegreePercentageData +from src.solver.embedding_solver import EmbeddingSolver, EvolutionParams +from src.util.logging import init_logger + +init_logger() +logger = logging.getLogger('evolution') + +stop = False + + +################################# Params ####################################### + +params = EvolutionParams( + population_size=12, + max_mutation_trials=30, + mutation_extend_to_free_neighbors_probability=0.3 # should be <=0.5 +) + +max_total = 1 +max_generations = 1000 +remove_redundancy_probability = 0.01 + +# Chimera graph +m = 2 # grid size +n = 2 # grid size +t = 4 # shore size + + +################################ Setup ######################################## + +H = TestGraph.crossed_house() +solver = EmbeddingSolver(H, m, n, t) +dp = DegreePercentageData(len(H.get_nodes())) + + +############################### Evolution ###################################### + +def main_loop(): + for i in range(max_total): + logger.info('') + logger.info('#############') + logger.info('🎈 NEW MAIN 🎈') + logger.info('#############') + logger.info('') + logger.info(f'Calling main: {i}') + + d = DrawEmbedding(m, n, t) + res = main(d) + save_final(d) + if res: + break + dp.plot_blocking() + + +def signal_handler(sig, frame): + # https://stackoverflow.com/questions/1112343/how-do-i-capture-sigint-in-python + global stop + stop = True + + +def main(d: DrawEmbedding) -> bool: + # logger.info('--- Main ---') + + # --- Clear + try: + shutil.rmtree('./out/') + except FileNotFoundError: + pass + os.mkdir('./out') + + # --- Init + solver.initialize_embedding() + save_embedding(*solver.get_embedding(), d, 'initial', + title=f'Initial embedding') + dp.save_current_degree_percentages(-1, solver._embedding) + + if solver.found_embedding(): + logger.info('🎉 Directly found embedding after initialization') + print('🎉 Directly found embedding after initialization') + # save_final(d) + output_embedding(*solver.get_embedding(), d) + return True + + # --- Start solver + for i in range(max_generations): + if stop: + print('Stop spawning new generations') + break + + child = do_one_generation(i, solver) + + if not child: + logger.info('🔳 Stopping algorithm...') + return False + + solver.commit(child) + + # Save embedding every x steps + save_embedding_steps = 1 + if (i % save_embedding_steps == 0) \ + or (i == max_generations - 2) or (i == max_generations - 1): + save_embedding(*solver.get_embedding(), d, str(i), + title=f'Generation {i}') + + # Save degree percentage data + dp.save_current_degree_percentages(i, solver._embedding) + + # Check if done + if child.is_valid_embedding(): + save_embedding(*solver.get_embedding(), d, str(i), + title=f'Generation {i} (final)') + child.remove_redundancy() + save_embedding(*solver.get_embedding(), d, f'{i}final', + title=f'Generation {i} (final with redundancy removed)') + logger.info('🎉🎉🎉🎉🎉🎉 Found embedding') + print('🎉🎉🎉🎉🎉🎉 Found embedding') + return True + else: + logger.info('✅ Generation passed') + + return False + + +def do_one_generation(i: int, solver: EmbeddingSolver) -> Optional[Embedding]: + logger.info('') + logger.info(f'🔄 Generation: {i}') + + child = solver.generate_population_and_select(params) + if not child: + return None + + # Leave "room" on graph for next generation + if random() < remove_redundancy_probability: + child.remove_redundancy() + + return child + + +################################ Output ######################################## + +def output_embedding(nodes, edges, mapping_G_to_H, d: DrawEmbedding): + logger.info('*** Embedding ***') + logger.info(nodes) + logger.info(edges) + logger.info(mapping_G_to_H) + + d.draw_chimera_and_embedding(nodes, edges, mapping_G_to_H) + d.show_embedding() + + +def save_embedding(nodes: set[int], edges: set[tuple[int, int, int]], + mapping_G_to_H, d: DrawEmbedding, i: str, title=''): + logger.info('') + logger.info('🎈 Current embedding') + logger.info(f'edges: {edges}') + logger.info(f'mapping_G_to_H: {mapping_G_to_H}') + + d.draw_whole_embedding_step(nodes, edges, mapping_G_to_H, title=title) + d.save_and_clear(f'./out/{i}.svg') + + +def save_final(d: DrawEmbedding) -> None: + logger.info('Save final') + pass + # d.save_and_clear(f'./out/steps.svg') + + ################################ Main ########################################## if __name__ == "__main__": - main() + signal.signal(signal.SIGINT, signal_handler) + main_loop() diff --git a/python/src/solver/initialization.py b/python/src/solver/initialization.py new file mode 100644 index 0000000..d3b407b --- /dev/null +++ b/python/src/solver/initialization.py @@ -0,0 +1,127 @@ +import logging +import random + +from src.embedding.embedding import Embedding +from src.util.stack import Stack +from src.util.util import get_first_from + +logger = logging.getLogger('evolution') + + +class Initialization(): + + def __init__(self, embedding: Embedding) -> None: + self._embedding = embedding + + def init_basic_path(self) -> None: + """Inits the graph as path graph starting from vertex 0 in the Chimera graph. + The length is determined by the number of vertices of the minor to embed. + """ + # Init with path graph as long as H + # TODO: what if no path graph embedding is possible? When is this the case? + # Start at vertex 0 + + source = 0 + for _ in range(self._embedding.H.nodes_count-1): + # Choose random neighbor + neighbors = self._embedding.get_free_neighbors(source) + target = random.choice(list(neighbors)) + + # Embed + self._embedding.embed_edge(source, target) + + source = target + + def init_bfs(self): + """Traverses through H and inits graph H usugin breadth first search on H.""" + # Mark all vertices as not visited + visited = [False] * self._embedding.H.nodes_count + + queue = [] + + # Mark source node as visited + h = 0 # start with node 0 in graph H + queue.append(h) + visited[h] = True + + while queue: + # Dequeue node & get neighbors + h = queue.pop(0) + neighbors_h = self._embedding.H.get_neighbor_nodes(h) + # Filter out already visited nodes in H + neighbors_h = [h for h in neighbors_h + if not visited[h]] + + # Embed edges to all neighbors + if h == 0: + g = 0 # start with node 0 for embedding in graph G + else: + gs = self._embedding.get_nodes_G(h) + g = get_first_from(gs) + + free_neighbors_g = self._embedding.get_free_neighbors(g) + if len(free_neighbors_g) < len(neighbors_h): + raise RuntimeError( + 'Not enough free neighbors to embed node of H in G (breadth first search)') + + for neighbor_h in neighbors_h: + neighbor_h_on_g = self._embedding.get_nodes_G( + neighbor_h) + # Neighbor already embedded embedded? + if neighbor_h_on_g: + # Try to add edge + if self._embedding.exists_edge(g, neighbor_h_on_g): + self._embedding.embed_edge_with_mapping( + h, g, neighbor_h, neighbor_h_on_g) + else: + # do nothing (this edge is added later using chains) + pass + else: + # Choose random free neighbor + to_g = random.choice(list(free_neighbors_g)) + free_neighbors_g.remove(to_g) + + # Embed + self._embedding.embed_edge_with_mapping( + h, g, neighbor_h, to_g) + logger.info(f'Embedded edge: {g}-{to_g}') + + # Prepare queue to continue with adjacent nodes + queue.append(neighbor_h) + visited[h] = True + + def init_dfs(self): + """Inits G using depth first search.""" + visited = [False] * self._embedding.H.nodes_count + recursion_stack = Stack() + self._dfs(0, visited, recursion_stack) # start with node 0 + + def _dfs(self, to_h, visited, recursion_stack: Stack): + """Depth first search recurion""" + # Update status (visited array & recursion stack) + from_h = recursion_stack.peek() # peek first + recursion_stack.push(to_h) # then push + visited[to_h] = True + + if from_h != None: # from_h is None at the initial call of dfs() + # Get from_g + if from_h == 0: + from_g = 0 + else: + from_g = self._embedding.get_nodes_G(from_h) + from_g = get_first_from(from_g) # no chains yet + + free_neighbors_g = self._embedding.get_free_neighbors(from_g) + to_g = random.choice(list(free_neighbors_g)) + + # Embed + self._embedding.embed_edge_with_mapping( + from_h, from_g, to_h, to_g) + + # DFS recursion + neighbors_h = self._embedding.H.get_neighbor_nodes(to_h) + for neighbor_h in neighbors_h: + if not visited[neighbor_h]: + self._dfs(neighbor_h, visited, recursion_stack) + + recursion_stack.pop() diff --git a/python/src/solver/k4_results.py b/python/src/solver/k4_results.py index 4772ee5..b9153c5 100644 --- a/python/src/solver/k4_results.py +++ b/python/src/solver/k4_results.py @@ -1,17 +1,17 @@ from src.drawing.draw import Draw -from src.graphs.undirected_graphs import UndirectedGraphAdjList +from src.graph.undirected_graph import UndirectedGraphAdjList from src.solver.embedding_solver import EmbeddingSolver def init_H(): # K4 graph H = UndirectedGraphAdjList(4) - H._set_edge(0, 1) - H._set_edge(0, 2) - H._set_edge(0, 3) - H._set_edge(1, 2) - H._set_edge(1, 3) - H._set_edge(2, 3) + H.set_edge(0, 1) + H.set_edge(0, 2) + H.set_edge(0, 3) + H.set_edge(1, 2) + H.set_edge(1, 3) + H.set_edge(2, 3) return H @@ -47,7 +47,7 @@ def main(): return # --- Output - nodes, edges = playground.get_embedding() + nodes, edges, mapping_G_to_H = playground.get_embedding() length1 = len(found_embeddings) found_embeddings.add(frozenset(edges)) @@ -58,7 +58,6 @@ def main(): continue print(f'{i}: Is correct: {playground.is_valid_embedding()}') - mapping_G_to_H = playground.get_mapping_G_to_H() d.draw_to_big_plot(nodes, edges, mapping_G_to_H) i += 1 diff --git a/python/src/solver/supernode_extension.py b/python/src/solver/supernode_extension.py new file mode 100644 index 0000000..9ffcfde --- /dev/null +++ b/python/src/solver/supernode_extension.py @@ -0,0 +1,324 @@ +import logging +import random +from collections import namedtuple +from dataclasses import dataclass +from typing import Optional + +import numpy as np +from src.embedding.articulation_point import ArticulationPointCalculator +from src.embedding.embedding import Embedding, NoFreeNeighborNodes +from src.util.util import any_of_one_in_other, get_first_from + +SourceTargetPair = namedtuple('SourceTargetPair', 'source target') +logger = logging.getLogger('evolution') + + +@dataclass +class TargetParams(): + target: int + target_supernode: int + shifted_target: int + target_neighbors: set[int] + + +class SupernodeExtension(): + + def __init__(self, embedding: Embedding) -> None: + self._embedding = embedding + self._non_viable_extensions = [] + self.selection_chances = [] + + def extend_random_supernode_to_free_neighbors(self) -> Optional[Embedding]: + """Chooses a random supernode and extends it to a free neighbor.""" + logger.info('Trying to extend random supernode to free neighbors') + playground = self._embedding.get_playground() + + supernode = self._choose_random_supernode_with_bias() + supernode_nodes = self._embedding.get_nodes_in_supernode(supernode) + + max_trials = 10 + tried_nodes = set() + for _ in range(min(len(supernode_nodes), max_trials)): + source = random.choice(list(supernode_nodes - tried_nodes)) + + try: + free_neighbors = playground.get_free_neighbors(source) + except: + tried_nodes.add(source) + continue + + target = random.choice(list(free_neighbors)) + playground.construct_supernode(source, target) + logger.info(f'-> Extended node {source} (supernode: {supernode}) to {target}') + return playground + + logger.info(f'-> ❌ failed (for supernode {supernode})') + return None + + def _choose_random_supernode_with_bias(self) -> int: + """Randomly chooses a supernode from H such that supernodes, which have + the least number of edges to other supernodes embedded in G, are favored. + We also favor supernodes that have the smallest number of nodes. + Thus, we won't pick an element according to a uniform distribution, but to + a custom one (using numpy). + """ + supernodes = list(self._embedding.get_nodes_H()) + + if not len(self.selection_chances): + degree_percentages = self._embedding.get_supernode_degree_percentages() + + # Favor smaller supernodes + # Those get assigned an increased chance of being selected + max_favor_small_supernodes = 0.7 * max(degree_percentages.values()) + lin_increases = np.linspace( + max_favor_small_supernodes, 0, num=len(supernodes)) + supernodes_sorted = self._embedding.get_sorted_supernodes_by_size() + # we use the supernodes as indices for the linspace of increases here + increases = [lin_increases[node] for node in supernodes_sorted] + + # Calculate selection chances + selection_chances = np.array([(1-p) for p in degree_percentages.values()]) + selection_chances_without_increase = np.copy(selection_chances) + + # Norm + sum = np.sum(selection_chances_without_increase) + if sum != 0: + selection_chances_without_increase *= 1 / \ + np.sum(selection_chances_without_increase) + selection_chances += increases + selection_chances *= 1 / np.sum(selection_chances) + self.selection_chances = selection_chances + + np.set_printoptions(precision=2) + logger.info( + f'Selection chances (without increases) are: {selection_chances_without_increase}') + logger.info(f'Selection chances are: {selection_chances}') + + # Choose according to calculated chances + supernode = np.random.choice(supernodes, p=self.selection_chances) + return supernode + + def extend_random_supernode(self) -> Optional[Embedding]: + """Chooses a random supernode and extends it to an already embedded + neighbor node by "bumping" the neighbor to one of its free neighbors. + + When the embedded neighbor is bumped to a free neighbor, this algorithm + might construct another supernode for the neighbor in order to reach + every node that could previously be reached from the neighbor node.""" + pair = self._choose_source_and_target() + if not pair: + return None + source, target = pair.source, pair.target + logger.info(f'🔗🔗 Trying to construct: {source}, {target}') + if (source, target) in self._non_viable_extensions: + logger.info('❌ Already considered but not viable -> skip') + # TODO: Don't count this case as wasted mutation + return None + + try: + target_free_neighbors = self._embedding.get_free_neighbors(target) + except NoFreeNeighborNodes: + logger.info(f'❌ Target {target} has no free neighbors') + return None + + playground = self._embedding.get_playground() + + # --- Try out possible positions for shifted_target + # Always check if we can reach all super nodes previously connected + # to target from the shifted_target + target_neighbors = playground.get_embedded_neighbors(target) + target_neighbors.discard(source) # no need to reach source from shifted_target + target_supernode = playground.get_supernode(target) + logger.info(f'Target neighbors are: {target_neighbors}') + + for shifted_target in target_free_neighbors: + logger.info(f'▶ Try out shifted target on node: {shifted_target}') + p = TargetParams(target, target_supernode, shifted_target, target_neighbors) + res = self._construct_supernode_with_shifted_target(source, p) + if res: + return res + + # If it didn't work, mark the mutation as failed + self._non_viable_extensions.append((source, target)) + logger.info('❌ No viable supernode placement') + return None + + def _choose_random_embedded_node(self) -> int: + embedded_nodes = self._embedding.get_embedded_nodes() + node = random.choice(list(embedded_nodes)) + return node + + def _construct_supernode_with_shifted_target(self, + source: int, + p: TargetParams) -> Optional[Embedding]: + """Tries to embed the shifted target, so that the node placement is viable. + + This means that we check if the new place for ``target`` - which is + ``shifted_target`` - allows for the following edges: + - ``target`` - ``shifted_target`` + - ``shifted_target`` - ``target_neighbors`` (all embedded ``target`` neighbors) + """ + playground = self._embedding.get_playground() + # Get reachable neighbors + # has to be calculated prior to supernode handover (!) + shifted_target_reachable = playground.get_reachable_neighbors(p.shifted_target) + shifted_target_reachable.discard(source) + shifted_target_reachable.discard(p.target) + + # supernode handover from target to shifted_target + playground.construct_supernode(p.target, p.shifted_target) + playground.construct_supernode(source, p.target) + + if not p.target_neighbors: + logger.info(f'No target neighbors to check: {p.target_neighbors}') + return playground + + # Check that previous connections still work + # 1st strategy + neighbors_done = self._construct_with_one_chain(playground, p, shifted_target_reachable) + # 2nd strategy (complementing 1st strategy) + if not len(neighbors_done) == len(p.target_neighbors): + worked = self._construct_with_another_chain(playground, source, p, neighbors_done) + if not worked: + return None + + # Check if strategy really worked + if playground.check_supernode_connectiveness(p.target_supernode): + return playground + else: + logger.info(f'Supernode sanity not ensured.') + return None + + def _construct_with_one_chain(self, playground: Embedding, p: TargetParams, + shifted_target_reachable: set[int]) -> set[int]: + """Tries to construct the supernode extension with just one chain.""" + neighbors_done = set() + + for neighbor in p.target_neighbors: + target_neighbor = self.get_reachable_node_in_neighbor_supernode( + playground, neighbor, {p.shifted_target}, shifted_target_reachable) + + if target_neighbor != None: # might be node "0" + logger.info(f'Could reach {target_neighbor}') + neighbors_done.add(neighbor) + playground.embed_edge(p.shifted_target, target_neighbor) + else: + logger.info(f'Could not reach ' + f'(reachable nodes are: {shifted_target_reachable})') + # Continue normally with next neighbor as next one might be + # reachable with this strategy (we then try to reach the + # remaining neighbors with the next strategy). + + return neighbors_done + + def _construct_with_another_chain(self, playground: Embedding, source: int, + p: TargetParams, neighbors_done: set[int]) -> bool: + """Tries to construct another chain to see if we can reach + remaining neighbors.""" + try: + shifted_target_free_neighbors = playground.get_free_neighbors( + p.shifted_target) + except NoFreeNeighborNodes: + logger.info(f'Could not construct another supernode ' + f'from shifted_target: {p.shifted_target} ' + f'(no free neighbor of shifted_target)') + return None + shifted_target_partner = get_first_from(shifted_target_free_neighbors) + + logger.info(f'🔗 Trying to construct another supernode: ' + f'{p.shifted_target}, {shifted_target_partner}') + # Chain shifted target and shifted target partner + # prior to calling this, we need to make sure that shifted_target + # now has the prior supernode of target + # The call itself needs to take place prior to embedding edges outgoing + # from shifted_target_partner (otherwise shifted_target_partner would + # not have a viable supernode) + playground.construct_supernode(p.shifted_target, shifted_target_partner) + + # Do not try to compute shifted_target reachable again here (!) + # as these are different now since shifted_target has the previous + # supernode of target + shifted_target_partner_reachable = playground.get_reachable_neighbors( + shifted_target_partner) + shifted_target_partner_reachable.discard(source) + shifted_target_partner_reachable.discard(p.target) + + for neighbor in p.target_neighbors: + # Already checked neighbors with the one-chain strategy + if neighbor in neighbors_done: + continue + + target_neighbor = self.get_reachable_node_in_neighbor_supernode( + playground, neighbor, {p.shifted_target, shifted_target_partner}, + shifted_target_partner_reachable) + + if target_neighbor != None: + logger.info(f'Could reach (with 2nd chain) {target_neighbor}') + playground.embed_edge(shifted_target_partner, target_neighbor) + else: + logger.info(f'Could also not reach (reachable nodes are: ' + f'{shifted_target_partner_reachable})') + return False # did not achieve a viable mutation even with 2nd strategy + + return True + + def get_reachable_node_in_neighbor_supernode(self, playground: Embedding, + neighbor: int, ignore_neighbors: set[int], + reachable: set[int]) -> Optional[int]: + """We need to discard some nodes here as they are not actually part of the + neighbor supernode. This is because we construct supernodes first to be + able to embed edges correctly. However, we then need to compare with + the a priori state and not this temporary state, which is why we + have to discard some nodes.""" + neighbor_supernode = playground.get_supernode(neighbor) + neighbor_supernode_nodes = playground.get_nodes_in_supernode(neighbor_supernode) + for ignore in ignore_neighbors: + neighbor_supernode_nodes.discard(ignore) + + logger.info(f'? Can we reach neighbor {neighbor} ' + f'(supernode: {neighbor_supernode} -> {neighbor_supernode_nodes})') + reachable_neighbor = any_of_one_in_other(reachable, neighbor_supernode_nodes) + return reachable_neighbor + + def _choose_source_and_target(self) -> Optional[SourceTargetPair]: + supernode = self._choose_random_supernode_with_bias() + supernode_nodes = self._embedding.get_nodes_in_supernode(supernode) + + max_trials = 5 + for _ in range(max_trials): + source = random.choice(list(supernode_nodes)) + target = self._choose_neighbor_not_in_same_supernode(source, supernode) + if target: + return SourceTargetPair(source, target) + + logger.info(f'❌ Could not find a valid source/target pair') + return None + + def _choose_neighbor_not_in_same_supernode(self, source: int, + source_supernode: int) -> Optional[int]: + """Tries to randomly choose a neighbor (target) for the given source node + that is not in the same supernode as the source node AND that is not + an articulation point in its own supernode. + Returns nothing if this condition cannot be met for the given source node + and its neighbors.""" + targets_orig = self._embedding.get_embedded_neighbors(source) + targets = [] + for target in targets_orig: + # Is target in the same supernode as source? + if self._embedding.get_supernode(target) == source_supernode: + continue + + # Is target an articulation point? + target_supernode_nodes = self._embedding.get_nodes_in_supernode_of(target) + articulation_points = ArticulationPointCalculator(self._embedding.G_embedding)\ + .calc_articulation_points(target_supernode_nodes) + if target in articulation_points: + continue + + targets.append(target) + + if not targets: + return None + + target = random.choice(list(targets)) + return target diff --git a/python/src/util/logging.py b/python/src/util/logging.py new file mode 100644 index 0000000..71070b8 --- /dev/null +++ b/python/src/util/logging.py @@ -0,0 +1,32 @@ +import logging +import logging.handlers +import os + + +def disable_logger(): + logging.disable(logging.CRITICAL) + + +def init_logger(): + logger = logging.getLogger('evolution') + logger.setLevel(logging.DEBUG) + + # File handler + if not os.path.exists('./logs'): + os.mkdir('./logs/') + log_filename = './logs/evolution.log' + should_roll_over = os.path.isfile(log_filename) + log_handler = logging.handlers.RotatingFileHandler( + log_filename, mode='w', backupCount=100, encoding='utf-8', delay=True) + if should_roll_over: + log_handler.doRollover() + log_handler.setLevel(logging.DEBUG) + + logger.addHandler(log_handler) + + # write to stderr + console_handler = logging.StreamHandler() + console_handler.setLevel(logging.WARNING) + logging.getLogger().addHandler(console_handler) + +# disable_logger() diff --git a/python/src/util/stack.py b/python/src/util/stack.py new file mode 100644 index 0000000..2e8cbd1 --- /dev/null +++ b/python/src/util/stack.py @@ -0,0 +1,16 @@ +class Stack: + def __init__(self): + self.stack = [] + + def push(self, data): + self.stack.append(data) + + def peek(self): + if self.stack: + return self.stack[-1] + return None + + def pop(self): + if self.stack: + return self.stack.pop() + return None diff --git a/python/src/util/util.py b/python/src/util/util.py new file mode 100644 index 0000000..3df3807 --- /dev/null +++ b/python/src/util/util.py @@ -0,0 +1,16 @@ +from typing import Optional + + +def get_first_from(s: set[int]) -> int: + # https://stackoverflow.com/a/48874729/9655481 + for e in s: + return e + raise KeyError('Set is empty') + + +def any_of_one_in_other(set1: set[int], set2: set[int]) -> Optional[int]: + # https://stackoverflow.com/a/16138094/9655481 + for element in set1: + if element in set2: + return element + return None diff --git a/python/tests/test_embedding_solver.py b/python/tests/test_embedding_solver.py index e44edbd..f6ed8e8 100644 --- a/python/tests/test_embedding_solver.py +++ b/python/tests/test_embedding_solver.py @@ -1,45 +1,45 @@ -import unittest -from unittest.case import TestCase - -from src.embedding_solver import EmbeddingSolver -from src.graphs.undirected_graphs import UndirectedGraphAdjList - - -class Test_EmbeddingSolver(TestCase): - - def test_init_basic_path(self): - for i in range(0, 8): - for j in range(10): - H = UndirectedGraphAdjList(i) # init minor - if i < 2: - self.assertRaises(NameError, EmbeddingSolver, H) - continue - solver = EmbeddingSolver(H) - solver.init_basic_path() - nodes, edges = solver.get_embedding() - self.assertEqual(len(nodes), i) - - def test_cost_stay_the_same_for_same_inits(self): - cost_fixed = -1 - - for i in range(20): - H = UndirectedGraphAdjList(5) - H._set_edge(0, 1) - H._set_edge(1, 2) - H._set_edge(1, 3) - H._set_edge(2, 3) - H._set_edge(3, 4) - H._set_edge(4, 0) - - solver = EmbeddingSolver(H) - solver.init_basic_path() - cost = solver.calculate_cost() - - if i == 0: - cost_fixed = cost - else: - self.assertEqual(cost, cost_fixed) - - -if __name__ == '__main__': - unittest.main() +# import unittest +# from unittest.case import TestCase + +# from src.graphs.undirected_graph import UndirectedGraphAdjList +# from src.solver.embedding_solver import EmbeddingSolver + + +# class Test_EmbeddingSolver(TestCase): + +# def test_init_basic_path(self): +# for i in range(0, 8): +# for j in range(10): +# H = UndirectedGraphAdjList(i) # init minor +# if i < 2: +# self.assertRaises(NameError, EmbeddingSolver, H) +# continue +# solver = EmbeddingSolver(H) +# solver.init_basic_path() +# nodes, edges = solver.get_embedding() +# self.assertEqual(len(nodes), i) + +# def test_cost_stay_the_same_for_same_inits(self): +# cost_fixed = -1 + +# for i in range(20): +# H = UndirectedGraphAdjList(5) +# H.set_edge(0, 1) +# H.set_edge(1, 2) +# H.set_edge(1, 3) +# H.set_edge(2, 3) +# H.set_edge(3, 4) +# H.set_edge(4, 0) + +# solver = EmbeddingSolver(H) +# solver.init_basic_path() +# cost = solver.calculate_cost() + +# if i == 0: +# cost_fixed = cost +# else: +# self.assertEqual(cost, cost_fixed) + + +# if __name__ == '__main__': +# unittest.main() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 219db95..cf20f98 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,6 @@ add_subdirectory(common) +add_subdirectory(lmrp) add_subdirectory(evolutionary) add_subdirectory(initial) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index eaaaed4..ff8e787 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,9 +1,16 @@ target_sources(majorminer PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/debug_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/graph_gen.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cut_vertex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/embedding_validator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/embedding_visualizer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/embedding_analyzer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/embedding_state.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/embedding_manager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/csc_problem.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/random_gen.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/time_measurement.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/graph_info.cpp ) diff --git a/src/config.hpp b/src/common/config.hpp similarity index 85% rename from src/config.hpp rename to src/common/config.hpp index 401e049..e187f5a 100644 --- a/src/config.hpp +++ b/src/common/config.hpp @@ -2,6 +2,7 @@ #define __MAJORMINER_CONFIG_HPP_ #define EIGEN_MPL2_ONLY +#define TBB_PREVIEW_CONCURRENT_LRU_CACHE 1 #define __DEBUG__ 1 diff --git a/src/common/csc_problem.cpp b/src/common/csc_problem.cpp new file mode 100644 index 0000000..a2c5ff1 --- /dev/null +++ b/src/common/csc_problem.cpp @@ -0,0 +1,71 @@ +#include "common/csc_problem.hpp" + +#include +#include +#include +#include +#include + +using namespace majorminer; + +adjacency_list_t majorminer::extractSubgraph(const EmbeddingBase& base, fuint32_t sourceNode) +{ + adjacency_list_t subgraph{}; + const auto& targetGraph = *base.getTargetGraph(); + base.iterateSourceMappingPair(sourceNode, + [&subgraph, &targetGraph](fuint32_t targetNodeA, fuint32_t targetNodeB){ + edge_t uv{targetNodeA, targetNodeB}; + edge_t vu{targetNodeB, targetNodeA}; + if (targetGraph.contains(uv) || targetGraph.contains(vu)) + { + subgraph.insert(uv); + subgraph.insert(vu); + } + }); + return subgraph; +} + +nodeset_t majorminer::getEmbeddedAdjacentSourceVertices(const EmbeddingBase& base, fuint32_t sourceVertex) +{ + const auto& mapping = base.getMapping(); + nodeset_t connections{}; + + base.iterateSourceGraphAdjacent(sourceVertex, [&](fuint32_t adjSourceNode){ + if (mapping.contains(adjSourceNode)) connections.insert(adjSourceNode); + }); + return connections; +} + +bool majorminer::isNodeCrucial(const EmbeddingBase& base, fuint32_t sourceNode, fuint32_t targetNode, fuint32_t conqueror) +{ + // 1. Check whether targetNode is crucial due to it being a cut vertex + // std::cout << "Checking whether cut vertex " << std::endl; + if (isCutVertex(base, sourceNode, targetNode)) return true; + // std::cout << "Is no cut vertex" << std::endl; + // 2. Check whether targetNode is crucial connections to other super vertices + nodeset_t connections = getEmbeddedAdjacentSourceVertices(base, sourceNode); + connections.unsafe_erase(conqueror); + + base.iterateSourceMappingAdjacentReverse(sourceNode, targetNode, [&](fuint32_t adjSourceNode){ + connections.unsafe_erase(adjSourceNode); + return connections.empty(); + }); + // std::cout << "Connections empty? " << connections.empty() << std::endl; + return !connections.empty(); +} + + +bool majorminer::connectsToAdjacentVertices(const EmbeddingManager& base, + const nodeset_t& placement, fuint32_t sourceVertex) +{ + nodeset_t connections = getEmbeddedAdjacentSourceVertices(base, sourceVertex); + + for (auto target : placement) + { + base.iterateTargetAdjacentReverseMapping(target, + [&connections](fuint32_t sourceAdj){ + connections.unsafe_erase(sourceAdj); + }); + } + return connections.empty(); +} diff --git a/src/common/csc_problem.hpp b/src/common/csc_problem.hpp new file mode 100644 index 0000000..b92b17b --- /dev/null +++ b/src/common/csc_problem.hpp @@ -0,0 +1,18 @@ +#ifndef __MAJORMINER_CSC_PROBLEM_HPP_ +#define __MAJORMINER_CSC_PROBLEM_HPP_ + +#include + +namespace majorminer +{ + adjacency_list_t extractSubgraph(const EmbeddingBase& base, fuint32_t sourceNode); + + nodeset_t getEmbeddedAdjacentSourceVertices(const EmbeddingBase& base, fuint32_t sourceVertex); + + bool isNodeCrucial(const EmbeddingBase& base, fuint32_t sourceNode, fuint32_t targetNode, fuint32_t conqueror); + + bool connectsToAdjacentVertices(const EmbeddingManager& base, const nodeset_t& placement, fuint32_t sourceVertex); +} + + +#endif \ No newline at end of file diff --git a/src/common/cut_vertex.cpp b/src/common/cut_vertex.cpp index 684886b..ca2a48d 100644 --- a/src/common/cut_vertex.cpp +++ b/src/common/cut_vertex.cpp @@ -1,6 +1,9 @@ #include "cut_vertex.hpp" +#include +#include + using namespace majorminer; typedef adjacency_list_t::const_iterator adj_list_const_it; @@ -9,13 +12,13 @@ typedef std::pair equal_range_t; struct VertexData { VertexData() - : m_parent((fuint32_t)-1), m_depth(m_parent), + : m_parent((vertex_t)-1), m_depth(m_parent), m_lowest(m_parent), m_recursed(false) {} - VertexData(fuint32_t parent, fuint32_t depth) + VertexData(vertex_t parent, fuint32_t depth) : m_parent(parent), m_depth(depth), m_lowest(depth), m_recursed(false) {} - fuint32_t m_parent; + vertex_t m_parent; fuint32_t m_depth; fuint32_t m_lowest; bool m_recursed; @@ -25,13 +28,12 @@ void majorminer::identifiyCutVertices(nodeset_t& cut, const adjacency_list_t& su { if (subgraph.empty()) return; Stack nodeStack{}; - Vector edgesDfs{}; - UnorderedMap properties{}; + UnorderedMap properties{}; - fuint32_t rootNode = subgraph.begin()->first; + vertex_t rootNode = subgraph.begin()->first; nodeStack.push(subgraph.equal_range(rootNode)); - properties.insert(std::make_pair(rootNode, VertexData{ (fuint32_t)-1, 0 })); + properties.insert(std::make_pair(rootNode, VertexData{ (vertex_t)-1, 0 })); fuint32_t depth = 1; fuint32_t rootChildren = 0; @@ -40,8 +42,8 @@ void majorminer::identifiyCutVertices(nodeset_t& cut, const adjacency_list_t& su auto& top = nodeStack.top(); if (top.first != top.second) { - fuint32_t currentNode = top.first->first; - fuint32_t nextNode = top.first->second; + vertex_t currentNode = top.first->first; + vertex_t nextNode = top.first->second; auto& p = properties[currentNode]; if (p.m_recursed) { // take care of last "recursion" (not actually recursing) @@ -78,11 +80,11 @@ void majorminer::identifiyCutVertices(nodeset_t& cut, const adjacency_list_t& su // Conduct a depth-first search that does not visit the vertex "node". // If all nodes were visited, then node is not a cut vertex -bool majorminer::isCutVertex(const adjacency_list_t& subgraph, fuint32_t node, fuint32_t n) +bool majorminer::isCutVertex(const adjacency_list_t& subgraph, vertex_t node, fuint32_t n) { auto nodeFind = subgraph.find(node); - if (nodeFind == subgraph.end()) return false; - fuint32_t rootNode = nodeFind->second; + if (nodeFind == subgraph.end()) return true; + vertex_t rootNode = nodeFind->second; if (rootNode == node) throw std::runtime_error("Loop inside subgraph!"); Stack nodeStack{}; @@ -96,7 +98,7 @@ bool majorminer::isCutVertex(const adjacency_list_t& subgraph, fuint32_t node, f auto& top = nodeStack.top(); if (top.first != top.second) { - fuint32_t nextNode = top.first->second; + vertex_t nextNode = top.first->second; top.first++; if (!visited.contains(nextNode)) { @@ -107,4 +109,68 @@ bool majorminer::isCutVertex(const adjacency_list_t& subgraph, fuint32_t node, f else nodeStack.pop(); } return visited.size() < n; +} + + + +bool majorminer::isCutVertex(const EmbeddingBase& base, vertex_t sourceNode, vertex_t targetNode) +{ + nodeset_t mapped {}; + insertMappedTargetNodes(base, mapped, sourceNode); + return isCutVertex(base, mapped, targetNode); +} + +bool majorminer::isCutVertex(const EmbeddingBase& base, nodeset_t& mappedNodes, vertex_t targetNode) +{ + if (mappedNodes.size() <= 1) return true; + mappedNodes.unsafe_erase(targetNode); + const auto& targetAdj = base.getTargetAdjGraph(); + vertex_t adjacentTarget = FUINT32_UNDEF; // cannot use targetNode here + auto range = targetAdj.equal_range(targetNode); + for (auto it = range.first; it != range.second; ++it) + { + if (mappedNodes.contains(it->second)) + { + adjacentTarget = it->second; + break; + } + } + if (!isDefined(adjacentTarget)) return true; + mappedNodes.unsafe_erase(adjacentTarget); + + Stack nodeStack{}; + nodeStack.push(targetAdj.equal_range(adjacentTarget)); + while(!nodeStack.empty()) + { + auto& top = nodeStack.top(); + if (top.first == top.second) nodeStack.pop(); + else if (top.first->second == targetNode) top.first++; + else + { + vertex_t next = top.first->second; + top.first++; + auto val = mappedNodes.unsafe_extract(next); + if (!val.empty()) + { + if (mappedNodes.empty()) return false; + nodeStack.push(targetAdj.equal_range(next)); + } + } + } + return !mappedNodes.empty(); +} + + +bool majorminer::areSetsConnected(const EmbeddingBase& base, const nodeset_t& setA, const nodeset_t& setB) +{ + bool connected = false; + for (auto target : setA) + { + base.iterateTargetGraphAdjacentBreak(target, [&](vertex_t adjTarget){ + if (setB.contains(adjTarget)) connected = true; + return connected; + }); + if (connected) return true; + } + return false; } \ No newline at end of file diff --git a/src/common/cut_vertex.hpp b/src/common/cut_vertex.hpp index 77344ba..21f3df5 100644 --- a/src/common/cut_vertex.hpp +++ b/src/common/cut_vertex.hpp @@ -1,8 +1,7 @@ #ifndef __MAJORMINER_CUT_VERTEX_HPP_ #define __MAJORMINER_CUT_VERTEX_HPP_ -#include "majorminer_types.hpp" -#include "common/utils.hpp" +#include namespace majorminer { @@ -11,8 +10,13 @@ namespace majorminer void identifiyCutVertices(nodeset_t& cut, const adjacency_list_t& subgraph, fuint32_t n); // check whether node is a cut vertex (needed for validation in FrontierShifting) - bool isCutVertex(const adjacency_list_t& subgraph, fuint32_t node, fuint32_t n); + bool isCutVertex(const adjacency_list_t& subgraph, vertex_t node, fuint32_t n); + // check whether targetNode (which is a node sourceNode is mapped to) is a cut vertex + bool isCutVertex(const EmbeddingBase& base, vertex_t sourceNode, vertex_t targetNode); + bool isCutVertex(const EmbeddingBase& base, nodeset_t& mappedNodes, vertex_t targetNode); + + bool areSetsConnected(const EmbeddingBase& base, const nodeset_t& setA, const nodeset_t& setB); } diff --git a/src/common/debug_utils.cpp b/src/common/debug_utils.cpp new file mode 100644 index 0000000..329c66e --- /dev/null +++ b/src/common/debug_utils.cpp @@ -0,0 +1,60 @@ +#include +#include + +#include + +using namespace majorminer; + + +void majorminer::printNodeset(const nodeset_t& nodeset) +{ + Vector nodes{}; + nodes.reserve(nodeset.size()); + nodes.assign(nodeset.begin(), nodeset.end()); + std::sort(nodes.begin(), nodes.end()); + + std::cout << "{"; + for (auto node : nodes) std::cout << " " << node; + std::cout << " }" << std::endl; +} + + +void majorminer::printAdjacencyList(const adjacency_list_t& adj) +{ + for (const auto& edge : adj) + { + std::cout << "(" << edge.first << ", " << edge.second << ")" << std::endl; + } +} + +void majorminer::printVertexNumberMap(const VertexNumberMap& m) +{ + for (const auto& p : m) + { + std::cout << "(" << p.first << ", " << p.second << ") "; + } + std::cout << std::endl; +} + +embedding_mapping_t majorminer::getReverseMapping(const embedding_mapping_t& mapping) +{ + embedding_mapping_t reverse{}; + for (const auto& mapped : mapping) reverse.insert(reversePair(mapped)); + return reverse; +} + +void majorminer::printEmbeddingOverlapStats(const embedding_mapping_t& mapping) +{ + VertexNumberMap overlapStat{}; + embedding_mapping_t reverse = getReverseMapping(mapping); + for (const auto& rev : reverse) + { + if(reverse.count(rev.first) > 1) overlapStat[rev.second]++; + } + Vector stats{}; + stats.reserve(overlapStat.size()); + for (const auto& p : overlapStat) stats.push_back(reversePair(p)); + std::sort(stats.begin(), stats.end(), PairFirstKeySorter()); + for (const auto& stat : stats) std::cout << "Source vertex " << stat.second << " is mapped onto " << stat.first << " vertices." << std::endl; +} + diff --git a/src/common/debug_utils.hpp b/src/common/debug_utils.hpp new file mode 100644 index 0000000..f242b45 --- /dev/null +++ b/src/common/debug_utils.hpp @@ -0,0 +1,22 @@ +#ifndef __MAJORMINER_DEBUG_UTILS_HPP_ +#define __MAJORMINER_DEBUG_UTILS_HPP_ + +#include + +namespace majorminer +{ + + #define TEST_OUTPUT(content) std::cout << #content << std::endl; + + void printAdjacencyList(const adjacency_list_t& adj); + + void printNodeset(const nodeset_t& nodeset); + + void printVertexNumberMap(const VertexNumberMap& m); + + embedding_mapping_t getReverseMapping(const embedding_mapping_t& mapping); + + void printEmbeddingOverlapStats(const embedding_mapping_t& mapping); +} + +#endif \ No newline at end of file diff --git a/src/common/embedding_analyzer.hpp b/src/common/embedding_analyzer.hpp index fe54fb3..58319d7 100644 --- a/src/common/embedding_analyzer.hpp +++ b/src/common/embedding_analyzer.hpp @@ -1,8 +1,6 @@ #ifndef __MAJORMINER_EMBEDDING_ANALYZER_HPP_ #define __MAJORMINER_EMBEDDING_ANALYZER_HPP_ -#include - #include "majorminer_types.hpp" namespace majorminer diff --git a/src/common/embedding_base.hpp b/src/common/embedding_base.hpp new file mode 100644 index 0000000..a7b6c0d --- /dev/null +++ b/src/common/embedding_base.hpp @@ -0,0 +1,197 @@ +#ifndef __MAJORMINER_EMBEDDING_BASE_HPP_ +#define __MAJORMINER_EMBEDDING_BASE_HPP_ + +#include + +namespace majorminer +{ + + class EmbeddingBase + { + public: + virtual ~EmbeddingBase(){} + + // getters + virtual const graph_t* getSourceGraph() const = 0; + virtual const graph_t* getTargetGraph() const = 0; + virtual const adjacency_list_t& getSourceAdjGraph() const = 0; + virtual const adjacency_list_t& getTargetAdjGraph() const = 0; + virtual const embedding_mapping_t& getMapping() const = 0; + virtual const embedding_mapping_t& getReverseMapping() const = 0; + virtual const nodeset_t& getNodesOccupied() const = 0; + virtual const nodeset_t& getRemainingTargetNodes() const = 0; + + + bool isTargetNodeOccupied(vertex_t targetNode) const { return getRemainingTargetNodes().contains(targetNode); } + virtual int numberFreeNeighborsNeeded(vertex_t sourceNode) const = 0; + + // Iteration methods + public: + + // For a given sourceNode, iterate over all target nodes sourceNode is mapped onto. + // For these target nodes, iterate over all their neighbors + // but skip a neighbor if skipOccupied && isOccupied(neighbor) + // Callback functor should take as parameters + // 1. fuint32_t target neighbor + // 2. fuint32_t target sourceNode is mapped onto + template + void iterateSourceMappingAdjacent(vertex_t sourceNode, Functor func) const + { + auto embeddedPathIt = getMapping().equal_range(sourceNode); + const auto& target = getTargetAdjGraph(); + const auto& remaining = getRemainingTargetNodes(); + + for (auto targetNode = embeddedPathIt.first; targetNode != embeddedPathIt.second; ++targetNode) + { + // find nodes that are adjacent to targetNode (in the targetGraph) + auto targetGraphAdjacentIt = target.equal_range(targetNode->second); + for (auto targetAdjacent = targetGraphAdjacentIt.first; targetAdjacent != targetGraphAdjacentIt.second; ++targetAdjacent) + { + if (skipOccupied && !remaining.contains(targetAdjacent->second)) continue; + if (func(targetAdjacent->second, targetNode->second)) return; + } + } + } + + template + void iterateReverseMapping(vertex_t mappedTargetNode, Functor func) const + { + auto revRange = getReverseMapping().equal_range(mappedTargetNode); + for (auto revIt = revRange.first; revIt != revRange.second; ++revIt) + { + func(revIt->second); + } + } + + // Iterate for a sourceNode over all target nodes source Node is mapped to. + // For these target nodes iterate over their adjacent nodes and for the adjacent nodes + // iterate over their reverse mapping. Awful everything. + template + void iterateSourceMappingAdjacentReverse(vertex_t sourceNode, vertex_t skipTarget, Functor func) const + { + auto embeddedPathIt = getMapping().equal_range(sourceNode); + const auto& target = getTargetAdjGraph(); + const auto& reverseMapping = getReverseMapping(); + + for (auto mapIt = embeddedPathIt.first; mapIt != embeddedPathIt.second; ++mapIt) + { + if (mapIt->second == skipTarget) continue; + auto targetGraphAdjacentIt = target.equal_range(mapIt->second); + for (auto targetAdjacent = targetGraphAdjacentIt.first; targetAdjacent != targetGraphAdjacentIt.second; ++targetAdjacent) + { + auto revRange = reverseMapping.equal_range(targetAdjacent->second); + for (auto revIt = revRange.first; revIt != revRange.second; ++revIt) + { + if (revIt->second != sourceNode && func(revIt->second)) return; + } + } + } + } + + template + void iterateTargetGraphAdjacent(vertex_t targetNode, Functor func) const + { + auto adjRange = getTargetAdjGraph().equal_range(targetNode); + for (auto adj = adjRange.first; adj != adjRange.second; ++adj) + { + func(adj->second); + } + } + + template + void iterateSourceGraphAdjacent(vertex_t sourceNode, Functor func) const + { + auto adjRange = getSourceAdjGraph().equal_range(sourceNode); + for (auto adj = adjRange.first; adj != adjRange.second; ++adj) + { + func(adj->second); + } + } + + template + void iterateSourceGraphAdjacentBreak(vertex_t sourceNode, Functor func) const + { + auto adjRange = getSourceAdjGraph().equal_range(sourceNode); + for (auto adj = adjRange.first; adj != adjRange.second; ++adj) + { + if (func(adj->second)) return; + } + } + + template + void iterateTargetGraphAdjacentBreak(vertex_t targetNode, Functor func) const + { + auto adjRange = getTargetAdjGraph().equal_range(targetNode); + for (auto adj = adjRange.first; adj != adjRange.second; ++adj) + { + if (func(adj->second)) return; + } + } + + template + void iterateTargetAdjacentReverseMapping(vertex_t target, Functor func) const + { + const auto& targetGraph = getTargetAdjGraph(); + const auto& reverse = getReverseMapping(); + auto adjacentRange = targetGraph.equal_range(target); + for (auto adjIt = adjacentRange.first; adjIt != adjacentRange.second; ++adjIt) + { + auto revMappedRange = reverse.equal_range(adjIt->second); + for (auto revIt = revMappedRange.first; revIt != revMappedRange.second; ++revIt) + { + func(revIt->second); + } + } + } + + + /// For a given source node, iterates over every pair of two target nodes the source node + /// is mapped to and invokes the functor func using this pair of target nodes. + template + void iterateSourceMappingPair(vertex_t sourceVertex, Functor func) const + { + const auto& mapping = getMapping(); + auto mappedRange = mapping.equal_range(sourceVertex); + for (auto mapped1It = mappedRange.first; mapped1It != mappedRange.second; ++mapped1It) + { + auto mapped2It = mapped1It; + mapped2It++; + + for (; mapped2It != mappedRange.second; ++mapped2It) + { + func(mapped1It->second, mapped2It->second); + } + } + } + + template + void iterateSourceMapping(vertex_t sourceVertex, Functor func) const + { + const auto& mapping = getMapping(); + auto mappingRange = mapping.equal_range(sourceVertex); + for (auto it = mappingRange.first; it != mappingRange.second; ++it) + { + func(it->second); + } + } + + template + void iterateFreeTargetAdjacent(vertex_t targetVertex, Functor func) const + { + const auto& remaining = getRemainingTargetNodes(); + const auto& targetGraph = getTargetAdjGraph(); + auto range = targetGraph.equal_range(targetVertex); + for (auto it = range.first; it != range.second; ++it) + { + if (remaining.contains(it->second)) func(it->second); + } + } + }; + + +} + + + + +#endif \ No newline at end of file diff --git a/src/common/embedding_manager.cpp b/src/common/embedding_manager.cpp new file mode 100644 index 0000000..7b98063 --- /dev/null +++ b/src/common/embedding_manager.cpp @@ -0,0 +1,219 @@ +#include "common/embedding_manager.hpp" + +#include +#include + +#define CACHE_CAPACITY 128 + +using namespace majorminer; + +namespace +{ + ShiftingCandidates getEmptyCandidate() + { + return ShiftingCandidates{0, std::shared_ptr() }; + } +} + +void EmbeddingManager::mapNode(fuint32_t node, fuint32_t targetNode) +{ + if (!m_changesToPropagate.empty()) synchronize(); + m_lastNode = node; + DEBUG(std::cout << node << " -> " << targetNode << std::endl;) + + m_nodesOccupied.insert(targetNode); + m_mapping.insert(std::make_pair(node, targetNode)); + m_reverseMapping.insert(std::make_pair(targetNode, node)); + m_targetNodesRemaining.unsafe_extract(targetNode); + m_state.mapNode(node, targetNode); +} + +void EmbeddingManager::mapNode(fuint32_t node, const nodeset_t& targetNodes) +{ + if (!m_changesToPropagate.empty()) synchronize(); + m_lastNode = node; + DEBUG(OUT_S << node << " -> {";) + for(auto targetNode : targetNodes) + { + DEBUG(OUT_S << " " << targetNode;) + m_nodesOccupied.insert(targetNode); + m_mapping.insert(std::make_pair(node, targetNode)); + m_reverseMapping.insert(std::make_pair(targetNode, node)); + m_targetNodesRemaining.unsafe_extract(targetNode); + + } + DEBUG(OUT_S << " }" << std::endl;) + m_state.mapNode(node, targetNodes); +} +#undef ADJUST + +void EmbeddingManager::unmapNode(vertex_t sourceVertex) +{ + auto range = m_mapping.equal_range(sourceVertex); + for (auto mappedIt = range.first; mappedIt != range.second; ++mappedIt) + { + eraseSinglePair(m_reverseMapping, mappedIt->second, mappedIt->first); + } + m_mapping.unsafe_erase(sourceVertex); + m_state.unmapNode(sourceVertex); +} + +EmbeddingManager::EmbeddingManager(EmbeddingSuite& suite, EmbeddingState& state) + : m_suite(suite), m_state(state), + m_candidateCache([](fuint32_t) {return getEmptyCandidate(); }, CACHE_CAPACITY), + m_nbCommitsRemaining(0), m_time(1) +{ + const auto& targetNodes = m_state.getRemainingTargetNodes(); + m_targetNodesRemaining.insert(targetNodes.begin(), targetNodes.end()); +} + + +void EmbeddingManager::setFreeNeighbors(fuint32_t node, fuint32_t nbNeighbors) +{ + m_changesToPropagate.push(EmbeddingChange{ChangeType::FREE_NEIGHBORS, node, nbNeighbors}); + m_sourceFreeNeighbors[node] = nbNeighbors; +} + +void EmbeddingManager::deleteMappingPair(fuint32_t source, fuint32_t target) +{ + m_changesToPropagate.push(EmbeddingChange{ChangeType::DEL_MAPPING, source, target}); + eraseSinglePair(m_mapping, source, target); + eraseSinglePair(m_reverseMapping, target, source); +} + +void EmbeddingManager::insertMappingPair(fuint32_t source, fuint32_t target) +{ + m_changesToPropagate.push(EmbeddingChange{ChangeType::INS_MAPPING, source, target}); + m_mapping.insert(std::make_pair(source, target)); + m_reverseMapping.insert(std::make_pair(target, source)); +} + +void EmbeddingManager::occupyNode(fuint32_t target) +{ + m_changesToPropagate.push(EmbeddingChange{ChangeType::OCCUPY_NODE, target}); + m_nodesOccupied.insert(target); + m_targetNodesRemaining.unsafe_erase(target); +} + +void EmbeddingManager::freeNode(fuint32_t target) +{ + m_changesToPropagate.push(EmbeddingChange{ChangeType::FREE_NODE, target}); + m_nodesOccupied.unsafe_erase(target); + m_targetNodesRemaining.insert(target); +} + +int EmbeddingManager::numberFreeNeighborsNeeded(fuint32_t sourceNode) const +{ // TODO: rework and correct?! + auto it = m_sourceFreeNeighbors.find(sourceNode); + return 2 * m_state.getSourceNeededNeighbors()[sourceNode].load() + - (it == m_sourceFreeNeighbors.end() ? 0 : std::max(it->second.load(), 0)); +} + +void EmbeddingManager::commit() +{ + m_changesToPropagate.push(EmbeddingChange{}); + m_nbCommitsRemaining++; +} + +void EmbeddingManager::synchronize() +{ + EmbeddingChange change{}; + auto& mapping = m_state.getMapping(); + auto& revMapping = m_state.getReverseMapping(); + auto& sourceFreeNeighbors = m_state.getSourceFreeNeighbors(); + auto& nodesOccupied = m_state.getNodesOccupied(); + auto& targetNodesRemaining = m_state.getRemainingTargetNodes(); + while(!m_changesToPropagate.empty() && m_nbCommitsRemaining > 0) + { + bool success = m_changesToPropagate.try_pop(change); + if (!success) break; + switch(change.m_type) + { + case ChangeType::DEL_MAPPING: + { + eraseSinglePair(mapping, change.m_a, change.m_b); + eraseSinglePair(revMapping, change.m_b, change.m_a); + m_changeHistory[change.m_a].m_timestampNodeChanged = m_time.load(); + break; + } + case ChangeType::INS_MAPPING: + { + mapping.insert(std::make_pair(change.m_a, change.m_b)); + revMapping.insert(std::make_pair(change.m_b, change.m_a)); + m_changeHistory[change.m_a].m_timestampNodeChanged = m_time.load(); + break; + } + case ChangeType::FREE_NEIGHBORS: + { + sourceFreeNeighbors[change.m_a] = change.m_b; + m_changeHistory[change.m_a].m_timestampEdgeChanged = m_time.load(); + break; + } + case ChangeType::OCCUPY_NODE: + { + targetNodesRemaining.unsafe_erase(change.m_a); + nodesOccupied.insert(change.m_a); + m_changeHistory[change.m_a].m_timestampNodeChanged = m_time.load(); + break; + } + case ChangeType::FREE_NODE: + { + targetNodesRemaining.insert(change.m_a); + nodesOccupied.unsafe_erase(change.m_a); + m_changeHistory[change.m_a].m_timestampNodeChanged = m_time.load(); + break; + } + case ChangeType::COMMIT: + { + m_nbCommitsRemaining--; + break; + } + } + } +} + +void EmbeddingManager::clear() +{ + for (auto& entry : m_changeHistory) + { + entry.second.clear(); + } + m_time = 0; + m_changesToPropagate.clear(); + m_nbCommitsRemaining = 0; +} + +ShiftingCandidates EmbeddingManager::getCandidatesFor(fuint32_t conquerorNode) +{ + auto handle = m_candidateCache[conquerorNode]; + if (handle) return handle.value(); + else return getEmptyCandidate(); +} + + +ShiftingCandidates EmbeddingManager::setCandidatesFor(fuint32_t conquerorNode, nodepairset_t& candidates) +{ + fuint32_t size = candidates.size(); + ShiftingCandidates element = std::make_pair(size, majorminer::make_shared_array(size)); + m_random.shuffle(element.second.get(), size); + fuint32_pair_t* writePtr = element.second.get(); + for (const auto& candidate : candidates) *writePtr++ = candidate; + m_candidateCache[conquerorNode].value() = element; + return element; +} + +EmbeddingVisualizer* EmbeddingManager::getVisualizer() +{ + return m_state.getVisualizer(); +} + +const graph_t* EmbeddingManager::getSourceGraph() const { return m_state.getSourceGraph(); } +const graph_t* EmbeddingManager::getTargetGraph() const { return m_state.getTargetGraph(); } +const adjacency_list_t& EmbeddingManager::getSourceAdjGraph() const { return m_state.getSourceAdjGraph(); } +const adjacency_list_t& EmbeddingManager::getTargetAdjGraph() const { return m_state.getTargetAdjGraph(); } +const embedding_mapping_t& EmbeddingManager::getMapping() const { return m_mapping; } +const embedding_mapping_t& EmbeddingManager::getReverseMapping() const { return m_reverseMapping; } +const nodeset_t& EmbeddingManager::getNodesOccupied() const { return m_nodesOccupied; } +const nodeset_t& EmbeddingManager::getRemainingTargetNodes() const { return m_targetNodesRemaining; } + + diff --git a/src/common/embedding_manager.hpp b/src/common/embedding_manager.hpp new file mode 100644 index 0000000..97ca21e --- /dev/null +++ b/src/common/embedding_manager.hpp @@ -0,0 +1,123 @@ +#ifndef __MAJORMINER_EMBEDDING_MANAGER_HPP +#define __MAJORMINER_EMBEDDING_MANAGER_HPP + +#include +#include +#include + +namespace majorminer +{ + enum ChangeType + { + DEL_MAPPING, + INS_MAPPING, + FREE_NEIGHBORS, + OCCUPY_NODE, + COMMIT, + FREE_NODE + }; + + struct EmbeddingChange + { + EmbeddingChange() + : m_type(ChangeType::COMMIT), m_a((fuint32_t)-1), + m_b((fuint32_t)-1){} + EmbeddingChange(ChangeType t, fuint32_t a) + : m_type(t), m_a(a), m_b((fuint32_t)-1) {} + EmbeddingChange(ChangeType t, fuint32_t a, fuint32_t b) + : m_type(t), m_a(a), m_b(b) {} + + ChangeType m_type; + fuint32_t m_a; + fuint32_t m_b; + }; + + struct NodeAffected + { + NodeAffected() + : m_timestampNodeChanged(0), + m_timestampEdgeChanged(0) {} + void clear() + { + m_timestampNodeChanged = 0; + m_timestampEdgeChanged = 0; + } + + fuint32_t m_timestampNodeChanged; + fuint32_t m_timestampEdgeChanged; + }; + + class EmbeddingManager : public EmbeddingBase + { + friend SuperVertexPlacer; + friend NetworkSimplexWrapper; + friend MutationManager; + public: + EmbeddingManager(EmbeddingSuite& suite, EmbeddingState& state); + void setFreeNeighbors(vertex_t node, fuint32_t nbNeighbors); + void deleteMappingPair(vertex_t source, vertex_t target); + void insertMappingPair(vertex_t source, vertex_t target); + void occupyNode(vertex_t target); + void freeNode(vertex_t target); + void synchronize(); + void commit(); + fuint32_t getTimestamp() { return m_time++; } + int numberFreeNeighborsNeeded(vertex_t sourceNode) const override; + const NodeAffected& getHistory(vertex_t node) { return m_changeHistory[node]; } + + const UnorderedMap>& getFreeNeighborMap() const { return m_sourceFreeNeighbors; } + + fuint32_t getLastNode() const { return m_lastNode; } + + ShiftingCandidates getCandidatesFor(vertex_t conquerorNode); + ShiftingCandidates setCandidatesFor(vertex_t conquerorNode, nodepairset_t& candidates); + + RandomGen& getRandomGen() { return m_random; } + + EmbeddingVisualizer* getVisualizer(); + + public: + const graph_t* getSourceGraph() const override; + const graph_t* getTargetGraph() const override; + const adjacency_list_t& getSourceAdjGraph() const override; + const adjacency_list_t& getTargetAdjGraph() const override; + const embedding_mapping_t& getMapping() const override; + const embedding_mapping_t& getReverseMapping() const override; + const nodeset_t& getNodesOccupied() const override; + const nodeset_t& getRemainingTargetNodes() const override; + + + private: + void unmapNode(vertex_t sourceVertex); + void mapNode(vertex_t source, vertex_t target); + void mapNode(vertex_t source, const nodeset_t& targets); + void clear(); + + private: + EmbeddingSuite& m_suite; + EmbeddingState& m_state; + CandidateCache m_candidateCache; + RandomGen m_random; + + embedding_mapping_t m_mapping; + embedding_mapping_t m_reverseMapping; + nodeset_t m_nodesOccupied; + nodeset_t m_targetNodesRemaining; + UnorderedMap> m_sourceFreeNeighbors; + Queue m_changesToPropagate; + std::atomic m_nbCommitsRemaining; + + UnorderedMap m_changeHistory; + + std::atomic m_time; + + fuint32_t m_lastNode = (fuint32_t)-1; + }; + + + +} + + + +#endif \ No newline at end of file diff --git a/src/common/embedding_state.cpp b/src/common/embedding_state.cpp new file mode 100644 index 0000000..e1c28c5 --- /dev/null +++ b/src/common/embedding_state.cpp @@ -0,0 +1,116 @@ +#include "embedding_state.hpp" + +#include "common/utils.hpp" + +using namespace majorminer; + +EmbeddingState::EmbeddingState(const graph_t& sourceGraph, const graph_t& targetGraph, EmbeddingVisualizer* vis) + : m_sourceGraph(&sourceGraph), m_targetGraph(&targetGraph), m_visualizer(vis) +{ + initialize(); +} + +void EmbeddingState::initialize() +{ + convertToAdjacencyList(m_source, *m_sourceGraph); + convertToAdjacencyList(m_target, *m_targetGraph); + for (const auto& arc : *m_targetGraph) + { + m_targetNodesRemaining.insert(arc.first); + m_targetNodesRemaining.insert(arc.second); + } + for (const auto& arc : *m_sourceGraph) + { + m_nodesRemaining[arc.first] = 0; + m_nodesRemaining[arc.second] = 0; + m_sourceNeededNeighbors[arc.first]++; + m_sourceNeededNeighbors[arc.second]++; + } + m_numberSourceVertices = m_nodesRemaining.size(); +} + +fuint32_t EmbeddingState::getTrivialNode() +{ // TODO: assert + auto node = *m_nodesRemaining.begin(); + m_nodesRemaining.unsafe_erase(m_nodesRemaining.begin()); + return node.first; +} + +bool EmbeddingState::removeRemainingNode(fuint32_t node) +{ + if (!m_nodesRemaining.contains(node)) return false; + m_nodesRemaining.unsafe_erase(node); + return true; +} + +void EmbeddingState::unmapNode(vertex_t sourceVertex) +{ + auto range = m_mapping.equal_range(sourceVertex); + for (auto mappedIt = range.first; mappedIt != range.second; ++mappedIt) + { + eraseSinglePair(m_reverseMapping, mappedIt->second, mappedIt->first); + } + m_mapping.unsafe_erase(sourceVertex); +} + +void EmbeddingState::updateNeededNeighbors(fuint32_t node) +{ + fuint32_t nbNodes = 0; + iterateSourceGraphAdjacent(node, [&, this](fuint32_t adjacentSource){ + if (isNodeMapped(adjacentSource)) + { + nbNodes++; m_sourceNeededNeighbors[adjacentSource]--; + } + }); + m_sourceNeededNeighbors[node] -= nbNodes; +} + + +void EmbeddingState::updateConnections(fuint32_t node, PrioNodeQueue& nodesToProcess) +{ + iterateSourceGraphAdjacent(node, [&](fuint32_t adjacent){ + auto findIt = m_nodesRemaining.find(adjacent); + if (findIt != m_nodesRemaining.end()) + { + findIt->second += 1; // one of its neighbors is now embedded + nodesToProcess.push(PrioNode{findIt->first, findIt->second}); + } + }); +} + +int EmbeddingState::numberFreeNeighborsNeeded(fuint32_t sourceNode) const +{ // TODO: rework + // std::cout << "Source node " << sourceNode << " needs " << m_sourceNeededNeighbors[sourceNode].load() << " neighbors and has " << m_sourceFreeNeighbors[sourceNode].load() << std::endl; + auto it = m_sourceNeededNeighbors.find(sourceNode); + return 2 * (it == m_sourceNeededNeighbors.end() ? 0 : it->second.load()) + - std::max(getSourceNbFreeNeighbors(sourceNode), 0); +} + +int EmbeddingState::getSourceNbFreeNeighbors(fuint32_t sourceNode) const +{ + auto it = m_sourceFreeNeighbors.find(sourceNode); + return it == m_sourceFreeNeighbors.end() ? 0 : it->second.load(); +} + + +void EmbeddingState::mapNode(fuint32_t source, fuint32_t targetNode) +{ + m_nodesOccupied.insert(targetNode); + m_mapping.insert(std::make_pair(source, targetNode)); + m_reverseMapping.insert(std::make_pair(targetNode, source)); + m_targetNodesRemaining.unsafe_extract(targetNode); + removeRemainingNode(source); +} + +void EmbeddingState::mapNode(fuint32_t source, const nodeset_t& targets) +{ + for (auto targetNode : targets) + { + m_nodesOccupied.insert(targetNode); + m_mapping.insert(std::make_pair(source, targetNode)); + m_reverseMapping.insert(std::make_pair(targetNode, source)); + m_targetNodesRemaining.unsafe_extract(targetNode); + } + removeRemainingNode(source); +} + diff --git a/src/common/embedding_state.hpp b/src/common/embedding_state.hpp new file mode 100644 index 0000000..03b14a8 --- /dev/null +++ b/src/common/embedding_state.hpp @@ -0,0 +1,97 @@ +#ifndef __MAJORMINER_EMBEDDING_STATE_HPP_ +#define __MAJORMINER_EMBEDDING_STATE_HPP_ + +#include +#include +#include +#include + +namespace majorminer +{ + + class EmbeddingState : public EmbeddingBase + { + friend EmbeddingManager; + public: + EmbeddingState(const graph_t& sourceGraph, const graph_t& targetGraph, EmbeddingVisualizer* vis); + + void mapNode(fuint32_t node, fuint32_t targetNode); + void mapNode(fuint32_t source, const nodeset_t& targets); + void updateNeededNeighbors(fuint32_t node); + void updateConnections(fuint32_t node, PrioNodeQueue& nodesToProcess); + int numberFreeNeighborsNeeded(fuint32_t sourceNode) const; + fuint32_t getTrivialNode(); + + bool removeRemainingNode(fuint32_t node); + bool isNodeMapped(fuint32_t sourceNode) const { return !m_nodesRemaining.contains(sourceNode); } + + bool isNodeOccupied(fuint32_t node) const { return m_nodesOccupied.contains(node); } + + fuint32_t getSuperVertexSize(fuint32_t sourceNode) const { return m_mapping.count(sourceNode); } + + int getSourceNbFreeNeighbors(fuint32_t sourceNode) const; + + ThreadManager& getThreadManager() { return m_threadManager; } + void setLMRPSubgraphGenerator(LMRPSubgraph* gen) { m_lmrpGen = gen; } + + public: // getter + const graph_t* getSourceGraph() const override { return m_sourceGraph; } + const graph_t* getTargetGraph() const override { return m_targetGraph; } + const adjacency_list_t& getSourceAdjGraph() const override { return m_source; } + const adjacency_list_t& getTargetAdjGraph() const override { return m_target; } + const embedding_mapping_t& getMapping() const override { return m_mapping; } + const embedding_mapping_t& getReverseMapping() const override { return m_reverseMapping; } + const nodeset_t& getNodesOccupied() const override { return m_nodesOccupied; } + const nodeset_t& getRemainingTargetNodes() const override { return m_targetNodesRemaining; } + + + embedding_mapping_t& getMapping() { return m_mapping; } + embedding_mapping_t& getReverseMapping() { return m_reverseMapping; } + nodeset_t& getNodesOccupied() { return m_nodesOccupied; } + nodeset_t& getRemainingTargetNodes() { return m_targetNodesRemaining; } + const UnorderedMap& getRemainingNodes() const { return m_nodesRemaining; } + UnorderedMap& getRemainingNodes() { return m_nodesRemaining; } + + EmbeddingVisualizer* getVisualizer() { return m_visualizer; } + bool hasVisualizer() const { return m_visualizer != nullptr; } + + UnorderedMap>& getSourceFreeNeighbors() { return m_sourceFreeNeighbors; } + UnorderedMap>& getSourceNeededNeighbors() { return m_sourceNeededNeighbors; } + + fuint32_t getNumberSourceVertices() const { return m_numberSourceVertices; } + + LMRPSubgraph* getSubgraphGen() { return m_lmrpGen; } + + private: + void initialize(); + void unmapNode(vertex_t sourceVertex); + + private: + const graph_t* m_sourceGraph; + const graph_t* m_targetGraph; + adjacency_list_t m_source; + adjacency_list_t m_target; + + embedding_mapping_t m_mapping; + embedding_mapping_t m_reverseMapping; + nodeset_t m_nodesOccupied; + nodeset_t m_targetNodesRemaining; + + UnorderedMap m_nodesRemaining; + UnorderedMap> m_sourceNeededNeighbors; + UnorderedMap> m_sourceFreeNeighbors; + nodeset_t m_sourceNodesAffected; + fuint32_t m_numberSourceVertices; + + EmbeddingVisualizer* m_visualizer; + + LMRPSubgraph* m_lmrpGen; + + ThreadManager m_threadManager; + }; + +} + + + +#endif diff --git a/src/common/embedding_validator.cpp b/src/common/embedding_validator.cpp index d8f6092..fd502bf 100644 --- a/src/common/embedding_validator.cpp +++ b/src/common/embedding_validator.cpp @@ -1,33 +1,45 @@ #include "embedding_validator.hpp" +#include +#include + using namespace majorminer; bool EmbeddingValidator::isDisjoint() const { UnorderedSet nodesOccupied{}; - for (const auto& mapped : m_embedding) + const auto& embedding = m_state.getMapping(); + for (const auto& mapped : embedding) { - if (nodesOccupied.contains(mapped.second)) return false; + if (nodesOccupied.contains(mapped.second)) + { + DEBUG(OUT_S << "Not an injective mapping." << std::endl;) + DEBUG(printOverlappings();) + return false; + } nodesOccupied.insert(mapped.second); } return true; } +void EmbeddingValidator::printOverlappings() const +{ + fuint32_pair_t stats = calculateOverlappingStats(m_state); + std::cout << "Overlapping statistics:" << std::endl + << "Distinct overlaps: " << stats.first << std::endl + << "Total overlapping: " << stats.second << std::endl; +} bool EmbeddingValidator::nodesConnected() const { + const auto& embedding = m_state.getMapping(); + const auto& sourceGraph = *m_state.getSourceGraph(); UnorderedMultiMap adjacencies{}; - for (const auto& e : m_source) + for (const auto& e : sourceGraph) { adjacencies.insert(orderedPair(e)); } - UnorderedMultiMap reverseMapping{}; - for (const auto& mapped : m_embedding) - { - reverseMapping.insert(std::make_pair(mapped.second, mapped.first)); - } - UnorderedMap> adjacentNodes{}; auto groupIt = adjacencies.begin(); @@ -39,36 +51,28 @@ bool EmbeddingValidator::nodesConnected() const { adjacentNodes.insert(std::make_pair(it->second, false)); } - auto mappedRange = m_embedding.equal_range(groupIt->first); + auto mappedRange = embedding.equal_range(groupIt->first); // for each node in adjacentNodes search for adjacency to mappedNodes tbb::parallel_for_each(mappedRange.first, mappedRange.second, - [&adjacentNodes, &reverseMapping, this](fuint32_pair_t targetNodeP) { - auto targetNodeMapped = reverseMapping.equal_range(targetNodeP.second); - for (auto it = targetNodeMapped.first; it != targetNodeMapped.second; ++it) - { - if (adjacentNodes.contains(it->second)) - { - adjacentNodes[it->second] = true; - } - } - auto adjacentIt = this->m_target.equal_range(targetNodeP.second); - for (auto it = adjacentIt.first; it != adjacentIt.second; ++it) - { - auto revMappedIt = reverseMapping.equal_range(it->second); - for (auto revIt = revMappedIt.first; revIt != revMappedIt.second; ++revIt) - { - if (adjacentNodes.contains(revIt->second)) - { - adjacentNodes[revIt->second] = true; - } - } - } + [&](fuint32_pair_t targetNodeP) { + m_state.iterateReverseMapping(targetNodeP.second, [&](fuint32_t reverse){ + if (adjacentNodes.contains(reverse)) adjacentNodes[reverse] = true; + }); + + m_state.iterateTargetAdjacentReverseMapping(targetNodeP.second, [&](fuint32_t revSourceNode){ + if (adjacentNodes.contains(revSourceNode)) adjacentNodes[revSourceNode] = true; + }); }); for (const auto& adjNode : adjacentNodes) { - if (!adjNode.second) return false; + if (!adjNode.second) + { + DEBUG(OUT_S << "Not all edges embedded! Node " << adjNode.first << " is missing at least one edge." << std::endl;) + DEBUG(printMissingEdges(adjNode.first)); + return false; + } } groupIt = adjRange.second; } @@ -76,3 +80,24 @@ bool EmbeddingValidator::nodesConnected() const return true; } + +void EmbeddingValidator::printMissingEdges(fuint32_t node) const +{ + nodeset_t missingAdjacent{}; + + m_state.iterateSourceGraphAdjacent(node, [&missingAdjacent](fuint32_t adjacentSource) + { missingAdjacent.insert(adjacentSource); }); + + if (missingAdjacent.empty()) return; + + m_state.iterateSourceMappingAdjacent(node, [&](fuint32_t adjacent, fuint32_t){ + m_state.iterateReverseMapping(adjacent, [&](fuint32_t reverse){ + missingAdjacent.unsafe_erase(reverse); + }); + return false; + }); + + OUT_S << "Node " << node << " is missing edges to nodes { "; + for (auto missing : missingAdjacent) OUT_S << missing << " "; + OUT_S << "}" << std::endl; +} diff --git a/src/common/embedding_validator.hpp b/src/common/embedding_validator.hpp index 3e89fe2..5e58d0e 100644 --- a/src/common/embedding_validator.hpp +++ b/src/common/embedding_validator.hpp @@ -2,7 +2,6 @@ #define __MAJORMINER_EMBEDDING_VALIDATOR_HPP_ #include "majorminer_types.hpp" -#include "utils.hpp" namespace majorminer { @@ -10,18 +9,19 @@ namespace majorminer class EmbeddingValidator { public: - EmbeddingValidator(const embedding_mapping_t& embedding, - const graph_t& source, const adjacency_list_t& target) - : m_embedding(embedding), m_source(source), m_target(target){} + EmbeddingValidator(const EmbeddingState& state) + : m_state(state) {} bool isDisjoint() const; bool nodesConnected() const; bool isValid() const { return isDisjoint() && nodesConnected(); } private: - const embedding_mapping_t& m_embedding; - const graph_t& m_source; - const adjacency_list_t& m_target; + void printMissingEdges(vertex_t node) const; + void printOverlappings() const; + + private: + const EmbeddingState& m_state; }; } diff --git a/src/common/embedding_visualizer.cpp b/src/common/embedding_visualizer.cpp index f631457..464e87e 100644 --- a/src/common/embedding_visualizer.cpp +++ b/src/common/embedding_visualizer.cpp @@ -1,5 +1,8 @@ #include "embedding_visualizer.hpp" +#include +#include + using namespace majorminer; namespace fs = std::filesystem; @@ -37,11 +40,14 @@ void EmbeddingVisualizer::setupDrawing(const embedding_mapping_t& embedding) m_embedding = &embedding; m_svg << m_prepared; - double fontSize = getWidth() / 30; + double fontSize = std::min(getWidth() / 30, 40.0); + double y = 50 + fontSize / 2.0; std::stringstream titleText {}; titleText << "Iteration " << (m_iteration + 1) << ": "; - m_svg << "" << titleText.str(); + m_svg << "" << titleText.str(); } void EmbeddingVisualizer::draw(const embedding_mapping_t& embedding, const char* title) @@ -311,3 +317,27 @@ double KingsVisualizer::getHeight() const { return ((1 + m_nbRows * 2) * getNodeSize()); } + + +fuint32_t GenericVisualizer::insertEdge(Vector& /* coords */, const edge_t& /* edge */) +{ + return 0; +} + +Coordinate_t GenericVisualizer::insertNode(fuint32_t v) const +{ + auto findIt = m_coordinates.find(v); + if (findIt == m_coordinates.end()) throw std::runtime_error("Node not contained in coordinate map!"); + + return Coordinate_t{ (1 + findIt->second.first) * getNodeSize(), (1 + findIt->second.second) * getNodeSize() }; +} + +double GenericVisualizer::getWidth() const +{ + return ((2 + m_width) * getNodeSize()); +} + +double GenericVisualizer::getHeight() const +{ + return ((2 + m_height) * getNodeSize()); +} diff --git a/src/common/embedding_visualizer.hpp b/src/common/embedding_visualizer.hpp index 6908429..68f88ae 100644 --- a/src/common/embedding_visualizer.hpp +++ b/src/common/embedding_visualizer.hpp @@ -4,8 +4,6 @@ #include "majorminer_types.hpp" #include -#include -#include namespace majorminer { @@ -109,6 +107,30 @@ namespace majorminer fuint32_t m_nbRows; fuint32_t m_nbCols; }; + + typedef UnorderedMap coordinate_map_t; + class GenericVisualizer : public EmbeddingVisualizer + { + public: + GenericVisualizer(const graph_t& source, const graph_t& target, + std::string filename, const coordinate_map_t& coordinates, + double width, double height) + : EmbeddingVisualizer(source, target, std::move(filename)), + m_coordinates(coordinates), m_width(width), m_height(height) {} + + ~GenericVisualizer(){} + + protected: + fuint32_t insertEdge(Vector& coords, const edge_t& edge) override; + Coordinate_t insertNode(fuint32_t v) const override; + double getWidth() const override; + double getHeight() const override; + + private: + const coordinate_map_t& m_coordinates; + double m_width; + double m_height; + }; } diff --git a/src/common/graph_gen.cpp b/src/common/graph_gen.cpp index 6677175..a673d59 100644 --- a/src/common/graph_gen.cpp +++ b/src/common/graph_gen.cpp @@ -1,5 +1,12 @@ #include "graph_gen.hpp" +#include +#include +#include +#include + +#include + using namespace majorminer; graph_t majorminer::generate_chimera(fuint32_t rows, fuint32_t cols) @@ -197,3 +204,19 @@ graph_t majorminer::generate_petersen() }; return petersen; } + + +graph_t majorminer::generate_erdosrenyi(fuint32_t n, float probability) +{ + ProbabilisticDecision rand{}; + graph_t erdos{}; + for (fuint32_t i = 0; i < n; ++i) + { + for (fuint32_t j = i + 1; j < n; ++j) + { + if (rand(probability)) erdos.insert(std::make_pair(i,j)); + } + } + return erdos; +} + diff --git a/src/common/graph_gen.hpp b/src/common/graph_gen.hpp index 93621ae..28d39c0 100644 --- a/src/common/graph_gen.hpp +++ b/src/common/graph_gen.hpp @@ -1,12 +1,6 @@ #ifndef __MAJORMINER_GRAPH_GEN_HPP_ #define __MAJORMINER_GRAPH_GEN_HPP_ -#include -#include -#include -#include -#include - #include "majorminer_types.hpp" @@ -37,6 +31,10 @@ namespace majorminer /// Import an edge list from a character array. graph_t import_graph(const char* edgeList, size_t length); + // Generate an erdös-renyi graph on n vertices. For each pair of vertices + // create an edge between the pair with "probability" + graph_t generate_erdosrenyi(fuint32_t n, float probability); + } diff --git a/src/common/graph_info.cpp b/src/common/graph_info.cpp new file mode 100644 index 0000000..c5835d8 --- /dev/null +++ b/src/common/graph_info.cpp @@ -0,0 +1,15 @@ +#include + +using namespace majorminer; + +fuint32_t ChimeraGraphInfo::getXCoord(vertex_t vertex) const +{ + return (vertex % (m_width * 8)) / 8; +} + +fuint32_t ChimeraGraphInfo::getYCoord(vertex_t vertex) const +{ + return vertex / (m_width * 8); +} + + diff --git a/src/common/graph_info.hpp b/src/common/graph_info.hpp new file mode 100644 index 0000000..4e15d3f --- /dev/null +++ b/src/common/graph_info.hpp @@ -0,0 +1,43 @@ +#ifndef __MAJORMINER_GRAPH_INFO_HPP_ +#define __MAJORMINER_GRAPH_INFO_HPP_ + +#include + +namespace majorminer +{ + + struct ChimeraGraphInfo + { + ChimeraGraphInfo(): m_width(0), m_height(0) {} + ChimeraGraphInfo(fuint32_t width, fuint32_t height) + : m_width(width), m_height(height) {} + + fuint32_t getXCoord(vertex_t vertex) const; + fuint32_t getYCoord(vertex_t vertex) const; + fuint32_t getWidth() const { return m_width; } + fuint32_t getHeight() const { return m_height; } + + fuint32_t m_width; + fuint32_t m_height; + }; + + struct KingGraphInfo + { + KingGraphInfo(): m_width(0), m_height(0) {} + KingGraphInfo(fuint32_t width, fuint32_t height) + : m_width(width), m_height(height) {} + + fuint32_t getXCoord(vertex_t vertex) const { return vertex % m_width; } + fuint32_t getYCoord(vertex_t vertex) const { return vertex / m_width; } + fuint32_t getWidth() const { return m_width; } + fuint32_t getHeight() const { return m_height; } + + fuint32_t m_width; + fuint32_t m_height; + }; +} + + + + +#endif \ No newline at end of file diff --git a/src/common/random_gen.cpp b/src/common/random_gen.cpp new file mode 100644 index 0000000..7633e32 --- /dev/null +++ b/src/common/random_gen.cpp @@ -0,0 +1,30 @@ +#include "common/random_gen.hpp" + +using namespace majorminer; +RandomGen::RandomGen() + : m_generator(m_rdGen()), + m_shuffleGenerator(m_rdShuffle()) +{} + +fuint32_t RandomGen::getRandomUint(fuint32_t upper) +{ + std::uniform_int_distribution distribution(0, upper); + while(!m_lock.try_lock()) {} + + fuint32_t randomVal = distribution(m_generator); + + m_lock.unlock(); + return randomVal; +} + + +vertex_t RandomGen::getRandomVertex(const nodeset_t& vertices) +{ + if (vertices.empty()) return FUINT32_UNDEF; + fuint32_t idx = getRandomUint(vertices.size() - 1); + for (auto vertex : vertices) + { + if (idx-- == 0) return vertex; + } + return FUINT32_UNDEF; +} \ No newline at end of file diff --git a/src/common/random_gen.hpp b/src/common/random_gen.hpp new file mode 100644 index 0000000..1e610da --- /dev/null +++ b/src/common/random_gen.hpp @@ -0,0 +1,53 @@ +#ifndef __MAJORMINER_RANDOM_GEN_HPP_ +#define __MAJORMINER_RANDOM_GEN_HPP_ + +#include + +namespace majorminer +{ + + class RandomGen + { + public: + RandomGen(); + fuint32_t getRandomUint(fuint32_t upper); + + template + void shuffle(T* data, fuint32_t size) + { + if (size == 0) return; + while(!m_shuffleLock.try_lock()) {} + + std::shuffle(data, data + size, m_shuffleGenerator); + + m_shuffleLock.unlock(); + } + + vertex_t getRandomVertex(const nodeset_t& vertices); + + private: + std::mutex m_lock; + std::mutex m_shuffleLock; + std::random_device m_rdGen; + std::random_device m_rdShuffle; + std::default_random_engine m_generator; + std::default_random_engine m_shuffleGenerator; + }; + + template::value>> + struct ProbabilisticDecision + { + public: + ProbabilisticDecision() : m_gen(m_rd()), m_dist(static_cast(0.0), static_cast(1.0)) {} + T operator()() { return m_dist(m_gen); } + bool operator()(T value) { return m_dist(m_gen) < value; } + + private: + std::random_device m_rd; + std::mt19937 m_gen; + std::uniform_real_distribution m_dist; + }; +} + + +#endif \ No newline at end of file diff --git a/src/common/thread_manager.cpp b/src/common/thread_manager.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/common/thread_manager.hpp b/src/common/thread_manager.hpp new file mode 100644 index 0000000..eb1a3b5 --- /dev/null +++ b/src/common/thread_manager.hpp @@ -0,0 +1,39 @@ +#ifndef __MAJORMINER_THREAD_MANAGER_HPP_ +#define __MAJORMINER_THREAD_MANAGER_HPP_ + +#include +#include + +namespace majorminer +{ + + class ThreadManager + { + public: + ThreadManager(){} + + fuint32_t getAvailableThreads() const { return m_pool.get_thread_count(); } + + template + void runMultiple(const Functor& func, fuint32_t n) + { + for (fuint32_t i = 0; i < n; ++i) m_pool.push_task(func); + } + + template + void run(const Functor& func) + { + m_pool.push_task(func); + } + + void wait() { m_pool.wait_for_tasks(); } + + private: + thread_pool m_pool; + + }; + +} + + +#endif \ No newline at end of file diff --git a/src/common/time_measurement.cpp b/src/common/time_measurement.cpp new file mode 100644 index 0000000..4bb204b --- /dev/null +++ b/src/common/time_measurement.cpp @@ -0,0 +1,9 @@ +#include "common/time_measurement.hpp" + +namespace majorminer +{ + +double TIME_MUTATION = 0, TIME_REDUCE = 0; +double GENERATE_POP = 0, OPTIMIZE = 0; + +} diff --git a/src/common/time_measurement.hpp b/src/common/time_measurement.hpp new file mode 100644 index 0000000..a81d57d --- /dev/null +++ b/src/common/time_measurement.hpp @@ -0,0 +1,23 @@ +#ifndef __MAJORMINER_TIME_MEASUREMENT_HPP_ +#define __MAJORMINER_TIME_MEASUREMENT_HPP_ + +#include + +#define CHRONO_STUFF(t1, t2, diff, var, ...) \ + auto t1 = std::chrono::high_resolution_clock::now(); \ + __VA_ARGS__ \ + auto t2 = std::chrono::high_resolution_clock::now(); \ + std::chrono::duration diff = t2 - t1; \ + var+=diff.count(); + + +#define PRINT_TIME(name) std::cout << "Time: " << #name << ": " << name << std::endl; + +namespace majorminer +{ + extern double TIME_MUTATION, TIME_REDUCE; + extern double GENERATE_POP, OPTIMIZE; +} + + +#endif diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 1a78bec..414d971 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -1,4 +1,6 @@ -#include "utils.hpp" +#include "common/utils.hpp" + +#include using namespace majorminer; @@ -13,10 +15,71 @@ void majorminer::convertToAdjacencyList(adjacency_list_t& adj, const graph_t& gr }); } -void majorminer::printAdjacencyList(const adjacency_list_t& adj) + +void majorminer::insertMappedTargetNodes(const EmbeddingBase& base, nodeset_t& nodes, fuint32_t sourceNode) +{ + const auto& mapping = base.getMapping(); + auto equalRange = mapping.equal_range(sourceNode); + for (auto it = equalRange.first; it != equalRange.second; ++it) nodes.insert(it->second); +} + +nodeset_t majorminer::getVertices(const graph_t& graph) +{ + nodeset_t vertices{}; + for (const auto& edge : graph) + { + vertices.insert(edge.first); + vertices.insert(edge.second); + } + return vertices; +} + + +fuint32_pair_t majorminer::calculateOverlappingStats(const EmbeddingBase& base) +{ + fuint32_t distinct = 0; + fuint32_t total = 0; + nodeset_t targetVertices = getVertices(*base.getTargetGraph()); + const auto& reverse = base.getReverseMapping(); + + for (auto target : targetVertices) + { + fuint32_t nbMapped = reverse.count(target); + if (nbMapped >= 2) + { + distinct++; + total += nbMapped; + } + } + return std::make_pair(distinct, total); +} + +embedding_mapping_t majorminer::replaceMapping(const embedding_mapping_t& mapping, + const nodeset_t& targets, vertex_t source) { - for (const auto& edge : adj) + embedding_mapping_t adjusted{}; + adjusted.insert(mapping.begin(), mapping.end()); + adjusted.unsafe_erase(source); + for (auto target : targets) { - std::cout << "(" << edge.first << ", " << edge.second << ")" << std::endl; + adjusted.insert(std::make_pair(source, target)); } + return adjusted; } + +fuint32_t majorminer::calculateFitness(const EmbeddingBase& state, const nodeset_t& superVertex) +{ + const auto& reverse = state.getReverseMapping(); + fuint32_t fitness = 0; + for (vertex_t target : superVertex) + { + fitness += reverse.count(target); + } + return fitness; +} + +bool majorminer::containsEdge(const graph_t& graph, edge_t edge) +{ + return graph.contains(orderedPair(edge)); +} + diff --git a/src/common/utils.hpp b/src/common/utils.hpp index e842418..7c6e72c 100644 --- a/src/common/utils.hpp +++ b/src/common/utils.hpp @@ -1,9 +1,8 @@ #ifndef __MAJORMINER_UTILS_HPP_ #define __MAJORMINER_UTILS_HPP_ -#include - -#include "majorminer_types.hpp" +#include +#include namespace majorminer @@ -29,8 +28,6 @@ namespace majorminer template void setMax(T& val, const T& v) { if (v > val) val = v; } - void printAdjacencyList(const adjacency_list_t& adj); - template void eraseSinglePair(UnorderedMultiMap& umap, const K& key, const V& val) { @@ -44,6 +41,83 @@ namespace majorminer } } } + + template + bool containsPair(const UnorderedMultiMap& umap, const K& key, const V& val) + { + auto range = umap.equal_range(key); + for (auto it = range.first; it != range.second; ++it) + { + if (it->second == val) + { + return true; + } + } + return false; + } + + void insertMappedTargetNodes(const EmbeddingBase& base, nodeset_t& nodes, fuint32_t sourceNode); + + inline bool isDefined(fuint32_t value) { return value != FUINT32_UNDEF; } + inline bool isDefined(fuint32_pair_t& p) { return isDefined(p.first) && isDefined(p.second); } + inline bool isDefined(NodePair& p) { return isDefined(p.source) && isDefined(p.target); } + + template + inline std::shared_ptr make_shared_array(std::size_t size) + { + return std::shared_ptr( new T[size], []( T *p ){ delete [] p; } ); + } + + template + inline bool overlappingSets(const UnorderedSet& map1, const UnorderedSet& map2) + { + for (const auto& key : map1) + { + if (map2.contains(key)) return true; + } + return false; + } + + template + inline void clearStack(Stack& s) + { + while(!s.empty()) s.pop(); + } + + nodeset_t getVertices(const graph_t& graph); + + fuint32_pair_t calculateOverlappingStats(const EmbeddingBase& base); + + // inefficient - just for visualization + embedding_mapping_t replaceMapping(const embedding_mapping_t& mapping, + const nodeset_t& targets, vertex_t source); + + template + inline std::pair reversePair(const std::pair& p) + { + return std::make_pair(p.second, p.first); + } + + template + struct PairFirstKeySorter + { + bool operator()(const std::pair& p1, const std::pair& p2) + { + if(reverse) return p1.first < p2.first; + else return p1.first > p2.first; + } + }; + + // Calculate the fitness of an *unmapped* super vertex! Calculate number of overlappings + fuint32_t calculateFitness(const EmbeddingBase& state, const nodeset_t& superVertex); + + bool containsEdge(const graph_t& graph, edge_t edge); + + template + inline bool empty_range(const std::pair& range) + { + return range.first == range.second; + } } diff --git a/src/evolutionary/CMakeLists.txt b/src/evolutionary/CMakeLists.txt index e876882..36c3438 100644 --- a/src/evolutionary/CMakeLists.txt +++ b/src/evolutionary/CMakeLists.txt @@ -1,6 +1,7 @@ target_sources(majorminer PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/mutation_manager.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mutation_extend.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/frontier_shifting_data.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mutation_frontier_shifting.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/mutation_reduce_overlap.cpp ) \ No newline at end of file diff --git a/src/evolutionary/frontier_shifting_data.cpp b/src/evolutionary/frontier_shifting_data.cpp deleted file mode 100644 index 7acbfaa..0000000 --- a/src/evolutionary/frontier_shifting_data.cpp +++ /dev/null @@ -1,70 +0,0 @@ -#include "frontier_shifting_data.hpp" - -using namespace majorminer; - - - -void FrontierShiftingData::clear() -{ - m_victimSourceNode = -1; - m_victimSubgraph.clear(); - m_cutVertices.clear(); - m_victimConnections.clear(); - m_reverseConnections.clear(); -} - -void FrontierShiftingData::lostNode(fuint32_t conquered, fuint32_t conquerorSource) -{ - if (m_nbNodes <= 1) throw std::runtime_error("Bad number of nodes in frontiershifting data."); - m_nbNodes--; - m_cutVertices.clear(); - auto range = m_reverseConnections.equal_range(conquered); - for (auto it = range.first; it != range.second; ++it) - { - eraseSinglePair(m_victimConnections, it->second, it->first); - } - m_reverseConnections.unsafe_erase(range.first, range.second); - nodeset_t newConnections{}; - for (auto it = m_victimSubgraph.begin(); it !=m_victimSubgraph.end();) - { - if(it->first == conquered) - { - m_victimConnections.insert(edge_t{conquerorSource, it->second}); - m_reverseConnections.insert(edge_t{it->second, conquerorSource}); - } - if (it->first == conquered || it->second == conquered) - { - it = m_victimSubgraph.unsafe_erase(it); - } - else ++it; - } -} - -void FrontierShiftingData::addConnection(fuint32_t sourceFrom, fuint32_t targetTo) -{ - m_victimConnections.insert(edge_t{ sourceFrom, targetTo }); - m_reverseConnections.insert(edge_t{ targetTo, sourceFrom }); -} - -void FrontierShiftingData::findCutVertices() -{ - // frontiershifting is not allowed on cut vertices as removing them would - // disconnect the chain. Therefore, identify cut vertices beforehand - majorminer::identifiyCutVertices(m_cutVertices, m_victimSubgraph, m_nbNodes); -} - -void FrontierShiftingData::setNbNodes(fuint32_t nbNodes) -{ - m_nbNodes = nbNodes; -} - -bool FrontierShiftingData::isNowACutVertex(fuint32_t contested) const -{ - return majorminer::isCutVertex(m_victimSubgraph, contested, m_nbNodes); -} - -void FrontierShiftingData::setVictimSource(fuint32_t node) -{ - m_victimSourceNode = node; -} - diff --git a/src/evolutionary/frontier_shifting_data.hpp b/src/evolutionary/frontier_shifting_data.hpp deleted file mode 100644 index bc96733..0000000 --- a/src/evolutionary/frontier_shifting_data.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef __MAJORMINER_FRONTIER_SHIFTING_DATA_HPP_ -#define __MAJORMINER_FRONTIER_SHIFTING_DATA_HPP_ - -#include "majorminer_types.hpp" -#include "common/cut_vertex.hpp" -#include "common/utils.hpp" - - -namespace majorminer -{ - - struct FrontierShiftingData - { - FrontierShiftingData() : m_victimSourceNode((fuint32_t)-1) { } - void clear(); - void setNbNodes(fuint32_t nbNodes); - void setVictimSource(fuint32_t node); - void lostNode(fuint32_t conquered, fuint32_t conquerorSource); - void addConnection(fuint32_t sourceFrom, fuint32_t targetTo); - void findCutVertices(); - bool isNowACutVertex(fuint32_t contested) const; - - - fuint32_t m_victimSourceNode; - fuint32_t m_nbNodes; - adjacency_list_t m_victimSubgraph; - nodeset_t m_cutVertices; - - // source node (connected to victim) --> target node mapped to from victim - adjacency_list_t m_victimConnections; // all connections other nodes have to the victim's chain - adjacency_list_t m_reverseConnections; // reverse m_victimConnections - }; - -} - -#endif \ No newline at end of file diff --git a/src/evolutionary/generic_mutation.hpp b/src/evolutionary/generic_mutation.hpp index cc51591..03e7b8c 100644 --- a/src/evolutionary/generic_mutation.hpp +++ b/src/evolutionary/generic_mutation.hpp @@ -9,7 +9,24 @@ namespace majorminer { public: virtual ~GenericMutation() {} + + // fast check whether a mutation is still valid + virtual bool isValid() = 0; + + // Initial preparation or revalidating a preparation + virtual bool prepare() = 0; + + // Incorporate changes of this mutation virtual void execute() = 0; + + // Should an invalid mutation be requeued? Default: Yes. + virtual bool requeue() const { return true; } + + protected: + void generateTimestamp(); + + private: + fuint32_t m_timestamp; }; } diff --git a/src/evolutionary/mutation_extend.cpp b/src/evolutionary/mutation_extend.cpp index 70414aa..fb0d6f4 100644 --- a/src/evolutionary/mutation_extend.cpp +++ b/src/evolutionary/mutation_extend.cpp @@ -1,123 +1,98 @@ -#include "mutation_extend.hpp" +#include "evolutionary/mutation_extend.hpp" + +#include +#include +#include + +#include using namespace majorminer; -MutationExtend::MutationExtend(EmbeddingSuite* suite, fuint32_t sourceNode) - : m_suite(*suite) { - // check whether node needs more - int delta = std::max(suite->numberFreeNeighborsNeeded(sourceNode), 0); - if (delta == 0) return; +MutationExtend::MutationExtend(const EmbeddingState& state, EmbeddingManager& embeddingManager, fuint32_t sourceNode) + : m_state(state), m_embeddingManager(embeddingManager), m_sourceVertex(sourceNode), + m_time(m_embeddingManager.getTimestamp()) { } - // find adjacent target node with highest number - auto mapRange = suite->m_mapping.equal_range(sourceNode); +// use embedding manager only +void MutationExtend::execute() +{ + // std::cout << "1. Extend execute node "<m_target.equal_range(targetNode->second); - for (auto adj = adjRange.first; adj != adjRange.second; ++adj) + m_embeddingManager.commit(); + + if (m_state.hasVisualizer()) { - if (m_suite.m_targetNodesRemaining.contains(adj->second)) - { // legitimate candidate - auto improvement = checkCandidate(adj->second, sourceNode, delta); - if (improvement < bestVal) - { - bestVal = improvement; - bestExtend = adj->second; - adjTargetNode = targetNode->second; - } - } + std::stringstream ss; + ss << "ExtendMutation applied " << m_sourceVertex + << " -> { ..., " << m_extendedTarget << " }; improvement: " + << improvement << std::endl; + m_embeddingManager.getVisualizer()->draw(m_embeddingManager.getMapping(), ss.str().c_str()); } } - - if (bestVal < 0) - { - DEBUG(OUT_S << "Emitting extend task for sourceNode=" << sourceNode - << " to extend to " << bestExtend << ". Improvement: " - << bestVal << std::endl;) - m_sourceVertex = sourceNode; - m_targetVertex = adjTargetNode; - m_extendedTarget = bestExtend; - m_valid = true; - } } -double MutationExtend::checkCandidate(fuint32_t extendNode, fuint32_t sourceNode, int delta) +double MutationExtend::checkImprovement(fuint32_t extendNode, const EmbeddingBase& base) { - m_degraded.clear(); + const auto& remainingTargetNodes = base.getRemainingTargetNodes(); double improvement = 0; - - auto adjRange = m_suite.m_target.equal_range(extendNode); - int nbFree = 0; - for (auto adj = adjRange.first; adj != adjRange.second; ++adj) - { - if (m_suite.m_targetNodesRemaining.contains(adj->second)) nbFree++; - else - { // already mapped to - // go over each that was mapped to this node and add to degraded - auto revIt = m_suite.m_reverseMapping.equal_range(adj->second); - for (auto rev = revIt.first; rev != revIt.second; ++rev) - { - m_degraded.insert(rev->second); - } - } - } - if (nbFree == 0) return MAXFLOAT; - improvement = - std::min(delta, nbFree) + 1; - for (auto deg : m_degraded) - { - if (improvement >= 0) return MAXFLOAT; - if (deg == extendNode) continue; - else - { - int needed = m_suite.numberFreeNeighborsNeeded(deg); - if (needed > -1) improvement++; - } - } + base.iterateTargetGraphAdjacent(extendNode, [&](fuint32_t adjacent){ + if (!remainingTargetNodes.contains(adjacent)) improvement -= 1; + }); return improvement; } -void MutationExtend::execute() +bool MutationExtend::prepare() { - if(!m_valid || !m_suite.m_targetNodesRemaining.contains(m_extendedTarget)) return; - int delta = m_suite.numberFreeNeighborsNeeded(m_sourceVertex); - if (delta <= 0) return; - double improvement = checkCandidate(m_extendedTarget, m_sourceVertex, delta); - if (improvement < 0) - { // adopt mutation - m_suite.m_targetNodesRemaining.unsafe_erase(m_extendedTarget); - m_suite.m_nodesOccupied.insert(m_extendedTarget); - m_suite.m_mapping.insert(std::make_pair(m_sourceVertex, m_extendedTarget)); - m_suite.m_reverseMapping.insert(std::make_pair(m_extendedTarget, m_sourceVertex)); + int delta = std::max(m_state.numberFreeNeighborsNeeded(m_sourceVertex), 0); + // std::cout << "Extend - node m_sourceVertex " << m_sourceVertex << " has delta of " << delta << std::endl; + if (delta == 0) return false; + const auto& remainingTargetNodes = m_state.getRemainingTargetNodes(); - for (auto deg : m_degraded) - { - if (deg != m_sourceVertex) m_suite.m_sourceFreeNeighbors[deg]--; - } - m_degraded.clear(); - auto embRange = m_suite.m_mapping.equal_range(m_sourceVertex); - for (auto embIt = embRange.first; embIt != embRange.second; ++embIt) - { - auto adjRange = m_suite.m_target.equal_range(embIt->second); - for (auto adjIt = adjRange.first; adjIt != adjRange.second; ++adjIt) - { - if (m_suite.m_targetNodesRemaining.contains(adjIt->second)) - { m_degraded.insert(adjIt->second); } - } - } - m_suite.m_sourceFreeNeighbors[m_sourceVertex] = m_degraded.size(); + double bestVal = MAXFLOAT; + fuint32_t bestExtend = -1; - if (m_suite.m_visualizer != nullptr) + nodeset_t candidates{}; + m_state.iterateSourceMappingAdjacent(m_sourceVertex, [&](fuint32_t neighbor, fuint32_t){ + if (remainingTargetNodes.contains(neighbor)) candidates.insert(neighbor); + return false; + }); + + for (auto& candidate : candidates) + { + double improvement = checkImprovement(candidate, m_state); + if (improvement < bestVal) { - std::stringstream ss; - ss << "ExtendMutation applied " << m_sourceVertex - << " -> { ..., " << m_extendedTarget << " }; improvement: " - << improvement << std::endl; - m_suite.m_visualizer->draw(m_suite.m_mapping, ss.str().c_str()); + bestVal = improvement; + bestExtend = candidate; } } + m_improving = bestVal < 0; + m_extendedTarget = bestExtend; + + m_time = m_embeddingManager.getTimestamp(); + return m_improving; } + +bool MutationExtend::isValid() +{ + // std::cout << "Time" << m_time << std::endl; + // std::cout <<"History "<< m_embeddingManager.getHistory(m_sourceVertex).m_timestampNodeChanged < +#include +#include +#include +#include + +#include + +#define MAX_CANDIDATES 20 + using namespace majorminer; +namespace +{ + bool isCandidateValid(const ShiftingCandidates& candidate) + { + return candidate.second.get() != nullptr; + } +} + +MutationFrontierShifting::MutationFrontierShifting(const EmbeddingState& state, EmbeddingManager& manager, + fuint32_t conquerorSource) + : m_state(state), m_manager(manager), m_conqueror(conquerorSource), + m_victim(FUINT32_UNDEF), m_valid(false) +{ } +bool MutationFrontierShifting::isValid() +{ + // std::cout << "Valid=" << m_valid << "; bestContested=" << m_bestContested << "; improvement=" << calculateImprovement(m_victim) + // << "; crucial=" << !isNodeCrucial(m_manager, m_victim, m_bestContested, m_conqueror) << std::endl; + // std::cout << "Victim=" << m_victim << "; Conqueror=" << m_conqueror << std::endl; + //char c=getchar(); + //if (c=='E') return false; + // std::cout << "------------------------------" << std::endl; + return m_valid + && containsPair(m_manager.getMapping(), m_victim, m_bestContested) + && isDefined(m_bestContested) && calculateImprovement(m_victim) < 0 + && !isNodeCrucial(m_manager, m_victim, m_bestContested, m_conqueror); +} -MuationFrontierShifting::MuationFrontierShifting(EmbeddingSuite* suite, - fuint32_t conquerorSource, fuint32_t victimSource) - : m_suite(*suite), m_conqueror(conquerorSource), - m_victim(victimSource), m_valid(false) +bool MutationFrontierShifting::prepare() { // find a victim node for which conqueror is connected to and // all other node is not crucial for victim - auto& data = m_suite.m_frontierData; - auto conquerorRange = data.m_victimConnections.equal_range(conquerorSource); - - for (auto candidateIt = conquerorRange.first; candidateIt != conquerorRange.second; ++candidateIt) + // std::cout << "Preparing shifting. " << m_conqueror << std::endl; + m_valid = false; + ShiftingCandidates cands = m_manager.getCandidatesFor(m_conqueror); + if (!isCandidateValid(cands) || true ) { - if (data.m_cutVertices.contains(candidateIt->second) || isCrucial(candidateIt->second)) continue; - double val = calculateImprovement(candidateIt->second); - if (val < m_bestImprovement) - { - m_bestImprovement = val; - m_valid = true; - m_bestContested = candidateIt->second; - } + nodepairset_t candidateSet{}; + m_state.iterateSourceMappingAdjacent(m_conqueror, [&](fuint32_t target, fuint32_t){ + m_state.iterateReverseMapping(target, [&](fuint32_t cand){ + if (cand != m_conqueror) candidateSet.insert(fuint32_pair_t{cand, target}); + }); + return candidateSet.size() > MAX_CANDIDATES; + }); + cands = m_manager.setCandidatesFor(m_conqueror, candidateSet); } -} -bool MuationFrontierShifting::isCrucial(fuint32_t candidateNode) -{ - auto& data = m_suite.m_frontierData; - auto revRange = data.m_reverseConnections.equal_range(candidateNode); - for (auto revIt = revRange.first; revIt != revRange.second; ++revIt) - { // for every node, we have to make sure that the source node has another - // connection to the victim chain - if (revIt->second == m_conqueror) continue; - bool replaceable = false; - auto connectionRange = data.m_victimConnections.equal_range(revIt->second); - for (auto it = connectionRange.first; it != connectionRange.second; ++it) + if (!isCandidateValid(cands)) return false; + fuint32_pair_t* candidates = cands.second.get(); + auto subgraph = extractSubgraph(m_state, m_conqueror); + + for (fuint32_t idx = 0; idx < cands.first; ++idx) + { + fuint32_pair_t candidate = candidates[idx]; + candidates[idx] = std::make_pair(FUINT32_UNDEF, FUINT32_UNDEF); + + if (!isDefined(candidate)) continue; + double improvement = calculateImprovement(candidate.first); + // std::cout << "Shifting " << m_conqueror << " - (" << candidate.first << "," << candidate.second << "): " << improvement << std::endl; + //if (improvement < 0) { char c = getchar(); if (c == 'E') return false; } + if (improvement < 0 && !isNodeCrucial(m_state, candidate.first, candidate.second, m_conqueror)) { - if (it->second != candidateNode) - { - replaceable = true; - break; - } + // std::cout << "Found valid shifting!" << std::endl; + m_bestImprovement = improvement; + m_valid = true; + m_bestContested = candidate.second; + m_victim = candidate.first; + break; } - if (!replaceable) return true; } - return false; + return m_valid; } -double MuationFrontierShifting::calculateImprovement(fuint32_t candidateNode) -{ - // Two factors play a role: - // 1. Change in chain length - // 2. Change in free neighbors - // TODO: add free neighbor calculation - fuint32_t victimLength = m_suite.m_mapping.count(m_victim); - fuint32_t conquerorLength = m_suite.m_mapping.count(m_conqueror); +double MutationFrontierShifting::calculateImprovement(fuint32_t victim) +{ // todo: generic on EmbeddingBase + int victimLength = static_cast(m_state.getSuperVertexSize(victim)); + int conquerorLength = static_cast(m_state.getSuperVertexSize(m_conqueror)); if (victimLength == 0) return MAXFLOAT; return pow(victimLength - 1, 2) + pow(conquerorLength + 1, 2) - pow(victimLength, 2) - pow(conquerorLength, 2); } -void MuationFrontierShifting::execute() +void MutationFrontierShifting::execute() { - auto& data = m_suite.m_frontierData; - if (!m_valid || isCrucial(m_bestContested)) return; - if (data.isNowACutVertex(m_bestContested) || calculateImprovement(m_bestContested) >= 0) return; - - // Commit the mutation - eraseSinglePair(m_suite.m_mapping, m_victim, m_bestContested); - eraseSinglePair(m_suite.m_reverseMapping, m_bestContested, m_victim); - m_suite.m_mapping.insert(fuint32_pair_t{ m_conqueror, m_bestContested }); - m_suite.m_reverseMapping.insert(fuint32_pair_t{ m_bestContested, m_conqueror }); + // std::cout << "Conqueror=" << m_conqueror << "; Contested=" << m_bestContested << "; Victim=" << m_victim << std::endl; + // getchar(); + m_manager.deleteMappingPair(m_victim, m_bestContested); + if (!containsPair(m_manager.getMapping(), m_conqueror, m_bestContested)) m_manager.insertMappingPair(m_conqueror, m_bestContested); + m_manager.commit(); - // take care of free neighbors and update frontierData - m_suite.m_frontierData.lostNode(m_bestContested, m_conqueror); - if (m_suite.m_visualizer != nullptr) + if (m_state.hasVisualizer()) { - m_suite.m_visualizer->draw(m_suite.m_mapping, [this](std::ostream& svg) + m_manager.getVisualizer()->draw(m_manager.getMapping(), [this](std::ostream& svg) { svg << "FrontierShifting. Conqueror " << this->getConqueror() << ", victim " diff --git a/src/evolutionary/mutation_frontier_shifting.hpp b/src/evolutionary/mutation_frontier_shifting.hpp index 9266398..65f9b2c 100644 --- a/src/evolutionary/mutation_frontier_shifting.hpp +++ b/src/evolutionary/mutation_frontier_shifting.hpp @@ -1,30 +1,31 @@ #ifndef __MAJORMINER_MUTATION_FRONTIER_SHIFTING_HPP_ #define __MAJORMINER_MUTATION_FRONTIER_SHIFTING_HPP_ -#include "evolutionary/generic_mutation.hpp" #include "majorminer_types.hpp" -#include "majorminer.hpp" +#include "evolutionary/generic_mutation.hpp" namespace majorminer { - class MuationFrontierShifting : public GenericMutation + class MutationFrontierShifting : public GenericMutation { public: - MuationFrontierShifting(EmbeddingSuite* suite, fuint32_t conquerorSource, fuint32_t victimSource); - ~MuationFrontierShifting() {} + MutationFrontierShifting(const EmbeddingState& state, EmbeddingManager& manager, fuint32_t conquerorSource); + ~MutationFrontierShifting() {} void execute() override; + bool isValid() override; + bool prepare() override; fuint32_t getConqueror() const { return m_conqueror; } fuint32_t getVictim() const { return m_victim; } fuint32_t getContested() const { return m_bestContested; } private: - bool isCrucial(fuint32_t candidateNode); - double calculateImprovement(fuint32_t candidateNode); + double calculateImprovement(fuint32_t victim); private: - EmbeddingSuite& m_suite; + const EmbeddingState& m_state; + EmbeddingManager& m_manager; fuint32_t m_conqueror; fuint32_t m_victim; fuint32_t m_bestContested; diff --git a/src/evolutionary/mutation_manager.cpp b/src/evolutionary/mutation_manager.cpp new file mode 100644 index 0000000..c0ac374 --- /dev/null +++ b/src/evolutionary/mutation_manager.cpp @@ -0,0 +1,152 @@ +#include "evolutionary/mutation_manager.hpp" + +#include +#include +#include +#include +#include + +#include + + +using namespace majorminer; + + +void MutationManager::operator()(bool finalIteration) +{ + if (!finalIteration) prepare(); + else prepareFinal(); + m_done = false; + m_runningPreps = 0; + m_wait = false; + + // one thread integrating mutations, other threads preparing new mutations + auto& prepQueue = m_prepQueue; + auto& incorporationQueue = m_incorporationQueue; + const auto& done = m_done; + auto& runningPreps = m_runningPreps; + auto& remaining = m_numberRemaining; + auto& free = m_free; + + auto prepareLambda = [&](){ + MutationPtr mutation; + while(!done) + { + bool success = prepQueue.try_pop(mutation); + if (!success) continue; + else + { + free.lock_shared(); + runningPreps++; + free.unlock_shared(); + bool valid = mutation->prepare(); + if (valid) incorporationQueue.push(std::move(mutation)); + else remaining--; + runningPreps--; + } + } + }; + + auto& threadManager = m_state.getThreadManager(); + fuint32_t threadCount = std::min(threadManager.getAvailableThreads() - 1, prepQueue.unsafe_size()); + threadManager.runMultiple(prepareLambda, threadCount); + incorporate(); + + threadManager.wait(); + m_embeddingManager.synchronize(); +} + +void MutationManager::prepare() +{ + clear(); + + // insert potential mutations + auto lastNode = m_embeddingManager.getLastNode(); + if (lastNode != (fuint32_t)-1) + { + prepareMutations(lastNode); + } + m_numberRemaining = m_prepQueue.unsafe_size(); +} + +void MutationManager::prepareFinal() +{ + clear(); + std::vector vertices{}; + vertices.reserve(m_state.getNumberSourceVertices()); + const auto& source = m_state.getSourceAdjGraph(); + + for (const auto& vertexPair : source) + { + if (vertices.empty() || vertices.back() != vertexPair.first) + { + vertices.push_back(vertexPair.first); + } + } + + + RandomGen rand{}; + rand.shuffle(vertices.data(), vertices.size()); + for (auto vertex : vertices) + { + m_prepQueue.push(std::make_unique(m_state, m_embeddingManager, vertex)); + } + m_numberRemaining = m_prepQueue.unsafe_size(); +} + +void MutationManager::clear() +{ + m_embeddingManager.clear(); + m_prepQueue.clear(); + m_incorporationQueue.clear(); +} + +void MutationManager::prepareMutations(fuint32_t node) +{ + nodeset_t affected{}; + m_state.iterateSourceMappingAdjacent(node, [&](fuint32_t target, fuint32_t /* */){ + m_state.iterateReverseMapping(target, [&](fuint32_t revSourceNode){ + affected.insert(revSourceNode); + }); + return false; + }); + affected.insert(node); + + for (auto candidate : affected) + { + m_prepQueue.push(std::make_unique(m_state, m_embeddingManager, candidate)); + m_prepQueue.push(std::make_unique(m_state, m_embeddingManager, candidate)); + } +} + + +void MutationManager::incorporate() +{ + MutationPtr mutation; + while(m_numberRemaining > 0) + { + bool success = m_incorporationQueue.try_pop(mutation); + if (!success) continue; + bool valid = mutation->isValid(); + if (!valid && mutation->requeue()) + { + m_prepQueue.push(std::move(mutation)); + m_wait = true; + } + else if (valid) + { + mutation->execute(); + m_numberRemaining--; + } + else m_numberRemaining--; + if (m_wait) + { + m_free.lock(); + while(m_runningPreps != 0) continue; + m_embeddingManager.synchronize(); + m_wait = false; + m_free.unlock(); + } + } + m_done = true; +} diff --git a/src/evolutionary/mutation_manager.hpp b/src/evolutionary/mutation_manager.hpp new file mode 100644 index 0000000..be7421c --- /dev/null +++ b/src/evolutionary/mutation_manager.hpp @@ -0,0 +1,43 @@ +#ifndef __MAJORMINER_MUTATION_MANAGER_HPP_ +#define __MAJORMINER_MUTATION_MANAGER_HPP_ + +#include + +#include + +namespace majorminer +{ + class MutationManager + { + typedef std::unique_ptr MutationPtr; + + public: + MutationManager(EmbeddingState& state, EmbeddingManager& embeddingManager) + : m_state(state), m_embeddingManager(embeddingManager) {} + + void operator()(bool finalIteration = false); + + private: + void clear(); + void prepare(); + void prepareFinal(); + void incorporate(); + void prepareMutations(fuint32_t node); + + private: + EmbeddingState& m_state; + EmbeddingManager& m_embeddingManager; + Queue m_prepQueue; + Queue m_incorporationQueue; + std::atomic m_done; + std::atomic m_runningPreps; + std::atomic m_wait; + + std::atomic m_numberRemaining; + std::shared_mutex m_free; + }; + +} + + +#endif \ No newline at end of file diff --git a/src/evolutionary/mutation_reduce_overlap.cpp b/src/evolutionary/mutation_reduce_overlap.cpp new file mode 100644 index 0000000..345de79 --- /dev/null +++ b/src/evolutionary/mutation_reduce_overlap.cpp @@ -0,0 +1,72 @@ +#include "mutation_reduce_overlap.hpp" + +#include + +#include +#include +#include +#include + +using namespace majorminer; + +MutationReduceOverlap::MutationReduceOverlap(EmbeddingState& state, + EmbeddingManager& manager, fuint32_t sourceVertex) + : m_state(state), m_manager(manager), m_sourceVertex(sourceVertex) +{ + m_reducer = new SuperVertexReducer{ m_state, sourceVertex }; +} + +MutationReduceOverlap::~MutationReduceOverlap() +{ + if (m_reducer != nullptr) delete m_reducer; +} + +bool MutationReduceOverlap::isValid() +{ + // std::cout << "Checking validity 0x" << ((void*)m_reducer) << std::endl; + // bool valid = m_reducer->remainsValid(m_manager); + // std::cout << "Is reduce overlap valid?." << valid << std::endl; + return m_reducer->remainsValid(m_manager); +} + +bool MutationReduceOverlap::prepare() +{ + m_requeues--; + m_reducer->initialize(); + m_reducer->optimize(); + // std::cout << "Has overlap improved. " << improved << std::endl; + return m_reducer->improved(); +} + +void MutationReduceOverlap::execute() +{ + // std::cout << "Trying to reduce overlap." << std::endl; + const auto& initial = m_reducer->getInitialSuperVertex(); + const auto& improved = m_reducer->getSuperVertex(); + const auto& reverse = m_manager.getReverseMapping(); + + for (auto target : initial) + { + if (!improved.contains(target)) + { + m_manager.deleteMappingPair(m_sourceVertex, target); + if (reverse.count(target) <= 1) m_manager.freeNode(target); + } + } + for (auto target : improved) + { + if (!initial.contains(target)) + { + m_manager.insertMappingPair(m_sourceVertex, target); + m_manager.occupyNode(target); + } + } + m_manager.commit(); + if (m_state.hasVisualizer()) + { + std::stringstream ss; + ss << "ReduceOverlap applied on " << m_sourceVertex << "." << std::endl; + m_manager.getVisualizer()->draw(m_manager.getMapping(), ss.str().c_str()); + } +} + diff --git a/src/evolutionary/mutation_reduce_overlap.hpp b/src/evolutionary/mutation_reduce_overlap.hpp new file mode 100644 index 0000000..82f3749 --- /dev/null +++ b/src/evolutionary/mutation_reduce_overlap.hpp @@ -0,0 +1,33 @@ +#ifndef __MAJORMINER_MUTATION_SIMPLE_REDUCE_OVERLAP_HPP_ +#define __MAJORMINER_MUTATION_SIMPLE_REDUCE_OVERLAP_HPP_ + +#include +#include + +#define MAX_REQUEUES 5 + +namespace majorminer +{ + class MutationReduceOverlap : public GenericMutation + { + public: + MutationReduceOverlap(EmbeddingState& state, EmbeddingManager& manager, fuint32_t sourceVertex); + ~MutationReduceOverlap(); + + bool prepare() override; + void execute() override; + bool isValid() override; + + bool requeue() const override { return m_requeues > 0; } + + private: + EmbeddingState& m_state; + EmbeddingManager& m_manager; + SuperVertexReducer* m_reducer; + fuint32_t m_sourceVertex; + fuint32_t m_requeues = MAX_REQUEUES; + }; +} + + +#endif \ No newline at end of file diff --git a/src/initial/CMakeLists.txt b/src/initial/CMakeLists.txt index 76796eb..8738494 100644 --- a/src/initial/CMakeLists.txt +++ b/src/initial/CMakeLists.txt @@ -1,4 +1,7 @@ target_sources(majorminer PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/super_vertex_reducer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/csc_evolutionary.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/super_vertex_placer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/network_simplex.cpp ) diff --git a/src/initial/csc_evolutionary.cpp b/src/initial/csc_evolutionary.cpp new file mode 100644 index 0000000..e591212 --- /dev/null +++ b/src/initial/csc_evolutionary.cpp @@ -0,0 +1,544 @@ +#include "initial/csc_evolutionary.hpp" + +#include +#include +#include +#include +#include + +#define POPULATION_SIZE 5 +#define ITERATION_LIMIT 10 +#define MAX_NEW_VERTICES 15 +#define REDUCE_ITERATION_COEFFICIENT 1 + +using namespace majorminer; + +namespace +{ + template + void swapPointers(T*& from, T*& to) + { + T*& temp = to; + to = from; + from = temp; + } +} + +EvolutionaryCSCReducer::EvolutionaryCSCReducer(EmbeddingState& state, + vertex_t sourceVertex) + : m_state(state), m_sourceVertex(sourceVertex), m_wasPlaced(true), + m_improved(false), m_visualizer(nullptr), m_threadManager(state.getThreadManager()) +{ + initialize(); +} + +EvolutionaryCSCReducer::EvolutionaryCSCReducer(EmbeddingState& state, + const nodeset_t& initial, vertex_t sourceVertex) + : m_state(state), m_sourceVertex(sourceVertex), m_wasPlaced(false), + m_improved(false), m_visualizer(nullptr), m_threadManager(state.getThreadManager()) +{ + initialize(initial); +} + +void EvolutionaryCSCReducer::optimize() +{ + if (!m_expansionPossible) return; + // double initialFitness = m_bestFitness; + Vector* current = &m_populationA; + Vector* next = &m_populationB; + + for (fuint32_t iteration = 0; iteration < ITERATION_LIMIT; ++iteration) + { + CHRONO_STUFF(t1,t2,diff1,OPTIMIZE, optimizeIteration(*current);) + if (m_visualizer != nullptr) visualize(iteration + 1, current); + + if (iteration + 1 != ITERATION_LIMIT) + { + CHRONO_STUFF(t3,t4,diff2,GENERATE_POP, + bool success = createNextGeneration(*current, *next); + if (!success) break;) + swapPointers(current, next); + } + } + if (m_visualizer != nullptr) visualize(FUINT32_UNDEF, nullptr); + // PRINT_TIME(TIME_MUTATION) + // PRINT_TIME(TIME_REDUCE) + // PRINT_TIME(OPTIMIZE) + // PRINT_TIME(GENERATE_POP) + // std::cout << initialFitness << " to " << m_bestFitness << " (" << m_bestSuperVertex.size() << ")" << std::endl; +} + +#define CREATE_STRING(vertices) \ + ss << "Final solution with fitness " << getFitness(vertices) << " and size " << vertices.size() << "."; + +#define CREATE_IT_STRING(vertices) \ + ss << "Iteration " << iteration << " individual " << (idx+1) << " has fitness " << getFitness(vertices) << " and size " << vertices.size() << "."; + + +void EvolutionaryCSCReducer::visualize(fuint32_t iteration, Vector* population) +{ + if (!isDefined(iteration)) + { + std::stringstream ss; + CREATE_STRING(m_bestSuperVertex); + embedding_mapping_t adjusted = replaceMapping(m_state.getMapping(), m_bestSuperVertex, m_sourceVertex); + m_visualizer->draw(adjusted, ss.str().c_str()); + } + else + { + std::stringstream ss; + for (fuint32_t idx = 0; idx < population->size(); ++idx) + { + const auto& placement = population->at(idx).getSuperVertex(); + CREATE_IT_STRING(placement) + embedding_mapping_t adjusted = replaceMapping(m_state.getMapping(), placement, m_sourceVertex); + m_visualizer->draw(adjusted, ss.str().c_str()); + ss.str(std::string()); + } + } + +} + + +void EvolutionaryCSCReducer::initialize() +{ + const auto& mapping = m_state.getMapping(); + const auto& reverse = m_state.getReverseMapping(); + auto range = mapping.equal_range(m_sourceVertex); + for (auto mappedIt = range.first; mappedIt != range.second; ++mappedIt) + { + m_bestSuperVertex.insert(mappedIt->second); + fuint32_t nbMapped = reverse.count(mappedIt->second); + m_vertexFitness.insert(std::make_pair(mappedIt->second, + nbMapped >= 1 ? nbMapped - 1 : 0)); + } + + setup(); +} + +void EvolutionaryCSCReducer::initialize(const nodeset_t& initial) +{ + m_bestSuperVertex.insert(initial.begin(), initial.end()); + + const auto& reverse = m_state.getReverseMapping(); + for (vertex_t target : m_bestSuperVertex) + { + m_vertexFitness.insert(std::make_pair(target, + reverse.count(target))); + } + setup(); +} + +void EvolutionaryCSCReducer::setup() +{ + if (!canExpand()) return; + + const auto& mapping = m_state.getMapping(); + + // Prepare adjacent source vertices + m_state.iterateSourceGraphAdjacent(m_sourceVertex, [&](vertex_t adjacentSource){ + if (mapping.contains(adjacentSource)) m_adjacentSourceVertices.insert(adjacentSource); + }); + + // Prepare intial "m_adjacentSources" adjacency list + for (vertex_t target : m_bestSuperVertex) prepareVertex(target, m_temporary, false); + + m_bestFitness = getFitness(m_bestSuperVertex); + initializePopulations(); +} + +void EvolutionaryCSCReducer::initializePopulations() +{ + m_populationA.resize(POPULATION_SIZE); + m_populationB.resize(POPULATION_SIZE); + + for (auto& individual : m_populationA) + { + individual.initialize(*this, m_sourceVertex); + individual.fromInitial(m_bestSuperVertex); // at this point m_bestSuperVertex is initial placement + } + for (auto& individual : m_populationB) + { + individual.initialize(*this, m_sourceVertex); + } +} + +bool EvolutionaryCSCReducer::canExpand() +{ + // Check whether there is some unoccupied adjacent target vertex + const auto& targetRemaining = m_state.getRemainingTargetNodes(); + m_expansionPossible = false; + for (vertex_t mappedTarget : m_bestSuperVertex) + { + m_state.iterateTargetGraphAdjacentBreak(mappedTarget, + [&](fuint32_t adjTarget){ + if (!m_bestSuperVertex.contains(adjTarget) && targetRemaining.contains(adjTarget)) + { + m_expansionPossible = true; + } + return m_expansionPossible; + }); + if (m_expansionPossible) return true; + } + return false; +} + + +void EvolutionaryCSCReducer::optimizeIteration(Vector& parentPopulation) +{ + // optimize all in parent population + #define MULTITHREADED 1 + #if MULTITHREADED == 1 + for (auto& parent : parentPopulation) + { + m_threadManager.run( [&]() { parent.optimize(); }); + } + m_threadManager.wait(); + #else + for (auto& parent : parentPopulation) parent.optimize(); + #endif + // sort parent population + std::sort(parentPopulation.begin(), parentPopulation.end(), std::less()); + + size_t newBestFitness = parentPopulation[0].getFitness(); + size_t size = parentPopulation.at(0).getSolutionSize(); + if (newBestFitness < m_bestFitness || + (newBestFitness == m_bestFitness && size < m_bestSuperVertex.size())) + { // adopt new superior solution + m_bestFitness = newBestFitness; + m_bestSuperVertex.clear(); + const auto& newSuperVertex = parentPopulation[0].getSuperVertex(); + m_bestSuperVertex.insert(newSuperVertex.begin(), newSuperVertex.end()); + m_improved = true; + } +} + +bool EvolutionaryCSCReducer::createNextGeneration(Vector& parentPopulation, + Vector& childPopulation) +{ + fuint32_t remainingAttemps = 5 * POPULATION_SIZE; + for (fuint32_t idx = 3; idx < POPULATION_SIZE && remainingAttemps > 0; --remainingAttemps) + { + const CSCIndividual* parentA = tournamentSelection(parentPopulation); + const CSCIndividual* parentB = tournamentSelection(parentPopulation); + bool success = childPopulation[idx].fromCrossover(*parentA, *parentB); + if (success) idx++; + // else std::cout << "Dead crossover!" << std::endl; + } + return remainingAttemps > 0; +} + +const CSCIndividual* EvolutionaryCSCReducer::tournamentSelection(const Vector& parentPopulation) +{ + fuint32_t max = POPULATION_SIZE - 1; + + const CSCIndividual* individualA = &parentPopulation.at(m_random.getRandomUint(max)); + const CSCIndividual* individualB = &parentPopulation.at(m_random.getRandomUint(max)); + return *individualA < *individualB ? individualA : individualB; +} + + +void EvolutionaryCSCReducer::prepareVertex(vertex_t target, nodeset_t& temp, bool count) +{ + if (!m_preparedVertices.contains(target)) + { + temp.clear(); + m_state.iterateTargetAdjacentReverseMapping(target, + [&](vertex_t adjacentSource){ + if (m_adjacentSourceVertices.contains(adjacentSource)) temp.insert(adjacentSource); + }); + m_state.iterateReverseMapping(target, [&](vertex_t source){ + if (m_adjacentSourceVertices.contains(source)) temp.insert(source); + }); + } + + m_prepareLock.lock(); + if (!m_preparedVertices.contains(target)) + { + for (vertex_t source : temp) + { + m_adjacentSources.insert(std::make_pair(target, source)); + } + const auto& reverse = m_state.getReverseMapping(); + if (count) m_vertexFitness.insert(std::make_pair(target, reverse.count(target))); + m_preparedVertices.insert(target); + } + m_prepareLock.unlock(); + temp.clear(); +} + +void EvolutionaryCSCReducer::addConnectivity(VertexNumberMap& connectivity, nodeset_t& temp, vertex_t target) +{ + if (!m_preparedVertices.contains(target)) prepareVertex(target, temp); + + auto range = m_adjacentSources.equal_range(target); + for (auto it = range.first; it != range.second; ++it) + { + connectivity[it->second]++; + } +} + +size_t EvolutionaryCSCReducer::getFitness(const nodeset_t& placement) const +{ + size_t fitness = 0; + VertexNumberMap::const_iterator findIt; + for (auto vertex : placement) + { + findIt = m_vertexFitness.find(vertex); + if (findIt != m_vertexFitness.end()) fitness += findIt->second; + } + return fitness; +} + +size_t EvolutionaryCSCReducer::getFitness(vertex_t target) const +{ + auto findIt = m_vertexFitness.find(target); + return findIt == m_vertexFitness.end() ? 0 : findIt->second; +} + +bool EvolutionaryCSCReducer::isRemoveable(VertexNumberMap& connectivity, vertex_t target) const +{ + auto range = m_adjacentSources.equal_range(target); + for (auto it = range.first; it != range.second; ++it) + { + if (connectivity[it->second] <= 1) return false; + } + return true; +} + +void EvolutionaryCSCReducer::removeVertex(VertexNumberMap& connectivity, vertex_t target) const +{ + auto range = m_adjacentSources.equal_range(target); + for (auto it = range.first; it != range.second; ++it) + { + auto findIt = connectivity.find(it->second); + if (findIt != connectivity.end()) findIt->second--; + } +} + +bool CSCIndividual::isConnected() const +{ + for (const auto& connect : m_connectivity) + { + if (connect.second == 0) return false; + } + return true; +} + +void CSCIndividual::initialize(EvolutionaryCSCReducer& reducer, vertex_t sourceVertex) +{ + m_reducer = &reducer; + m_state = &reducer.m_state; + m_sourceVertex = sourceVertex; + m_random = std::make_unique(); +} + + + +void CSCIndividual::fromInitial(const nodeset_t& placement) +{ + m_done = false; + m_superVertex.clear(); + m_superVertex.insert(placement.begin(), placement.end()); + + setupConnectivity(); +} + +bool CSCIndividual::fromCrossover(const CSCIndividual& individualA, const CSCIndividual& individualB) +{ + m_done = false; + m_superVertex.clear(); + const auto& superVertexA = individualA.getSuperVertex(); + const auto& superVertexB = individualB.getSuperVertex(); + // std::cout << "Crossover: overlapping - " << overlappingSets(superVertexA, superVertexB) << "; connected - " + // << areSetsConnected(*m_state, superVertexA, superVertexB) << std::endl; + if (!overlappingSets(superVertexA, superVertexB) + && !areSetsConnected(*m_state, superVertexA, superVertexB)) + { + m_done = true; + return false; + } + m_superVertex.insert(superVertexA.begin(), superVertexA.end()); + m_superVertex.insert(superVertexB.begin(), superVertexB.end()); + setupConnectivity(); + return true; +} + +void CSCIndividual::printConnectivity() const +{ + printVertexNumberMap(m_connectivity); +} + +void CSCIndividual::setupConnectivity() +{ + const auto& adjacentSourceVertices = m_reducer->getAdjacentSourceVertices(); + for (auto adjSource : adjacentSourceVertices) + { + m_connectivity[adjSource] = 0; + } + + for (auto target : m_superVertex) + { + m_reducer->addConnectivity(m_connectivity, m_temporarySet, target); + } +} + +void CSCIndividual::optimize() +{ + if (m_done) return; + CHRONO_STUFF(t1,t2,diff1,TIME_MUTATION, mutate();) + + CHRONO_STUFF(t3,t4,diff2, TIME_REDUCE, reduce();) + m_fitness = m_reducer->getFitness(m_superVertex); + m_done = true; +} + + +size_t CSCIndividual::getSolutionSize() const +{ + return m_superVertex.size(); +} + +size_t CSCIndividual::getFitness() const +{ + return m_fitness; +} + +void CSCIndividual::mutate() +{ + m_temporarySet.clear(); + for (vertex_t vertex : m_superVertex) + { + m_state->iterateFreeTargetAdjacent(vertex, + [&](vertex_t adjacentTarget){ + if(!m_superVertex.contains(adjacentTarget)) + { + m_temporarySet.insert(adjacentTarget); + } + }); + } + if (m_temporarySet.empty()) return; + + vertex_t startVertex = m_random->getRandomVertex(m_temporarySet); + + if (!isDefined(startVertex)) return; + m_temporarySet.clear(); + clearStack(m_iteratorStack); + + const auto& targetGraph = m_state->getTargetAdjGraph(); + const auto& remaining = m_state->getRemainingTargetNodes(); + + fuint32_t numberAdded = 1; + addVertex(startVertex); + m_iteratorStack.push(targetGraph.equal_range(startVertex)); + while(!m_iteratorStack.empty() && numberAdded <= MAX_NEW_VERTICES) + { + auto& top = m_iteratorStack.top(); + if (top.first == top.second) + { + m_iteratorStack.pop(); + continue; + } + vertex_t adjacent = top.first->second; + if (remaining.contains(adjacent) && !m_superVertex.contains(adjacent)) + { // add node + top.first++; + addVertex(adjacent); + numberAdded++; + m_iteratorStack.push(targetGraph.equal_range(adjacent)); + } + else + { + top.first++; + } + } +} + +void CSCIndividual::reduce() +{ + if (m_superVertex.size() <= 1) return; + m_vertexVector.resize(m_superVertex.size()); + fuint32_t idx = 0; + for (vertex_t vertex : m_superVertex) m_vertexVector[idx++] = vertex; + fuint32_t vectorSize = m_vertexVector.size(); + + // Try greedily reducing overlap vertices + for (idx = 0; idx < vectorSize;) + { + vertex_t* current = &m_vertexVector[idx]; + if (m_reducer->getFitness(*current) != 0 && tryRemove(*current)) + { + *current = m_vertexVector.back(); + m_vertexVector.resize(--vectorSize); + } + else idx++; + } + + // Try reducing all other vertices + fuint32_t maxIterations = REDUCE_ITERATION_COEFFICIENT * m_vertexVector.size(); + vectorSize = m_vertexVector.size(); + for (fuint32_t iteration = 0; iteration < maxIterations; ++iteration) + { + fuint32_t randomIdx = m_random->getRandomUint(vectorSize - 1); + vertex_t* current = &m_vertexVector[randomIdx]; + if (!m_superVertex.contains(*current) || tryDfsRemove(*current, iteration)) + { + *current = m_vertexVector.back(); + m_vertexVector.resize(--vectorSize); + } + } + + for (idx = 0; idx < vectorSize; ++idx) + { + if (m_superVertex.contains(m_vertexVector[idx])) tryRemove(m_vertexVector[idx]); + } +} + +void CSCIndividual::addVertex(vertex_t target) +{ + if (m_superVertex.contains(target)) return; + m_reducer->addConnectivity(m_connectivity, m_temporarySet, target); + m_superVertex.insert(target); +} + +bool CSCIndividual::tryRemove(vertex_t target) +{ + // Remove if not a cut vertex + if (!m_reducer->isRemoveable(m_connectivity, target)) return false; + + m_temporarySet.clear(); + m_temporarySet.insert(m_superVertex.begin(), m_superVertex.end()); + if (!isCutVertex(*m_state, m_temporarySet, target)) + { + m_reducer->removeVertex(m_connectivity, target); + m_superVertex.unsafe_erase(target); + return true; + } + m_temporarySet.clear(); + return false; +} + +bool CSCIndividual::tryDfsRemove(vertex_t target, fuint32_t& iteration) +{ + if (!tryRemove(target)) return false; + + const auto& targetGraph = m_state->getTargetAdjGraph(); + clearStack(m_iteratorStack); + m_iteratorStack.push(targetGraph.equal_range(target)); + while(!m_iteratorStack.empty()) + { + auto& top = m_iteratorStack.top(); + if (top.first == top.second) m_iteratorStack.pop(); + else if (m_superVertex.contains(top.first->second)) + { + vertex_t adjacent = top.first->second; + top.first++; + iteration++; + bool success = tryRemove(adjacent); + if (success) m_iteratorStack.push(targetGraph.equal_range(adjacent)); + } + else top.first++; + } + return true; +} + diff --git a/src/initial/csc_evolutionary.hpp b/src/initial/csc_evolutionary.hpp new file mode 100644 index 0000000..5e32054 --- /dev/null +++ b/src/initial/csc_evolutionary.hpp @@ -0,0 +1,120 @@ +#ifndef __MAJORMINER_CSC_EVOLUTIONARY_HPP_ +#define __MAJORMINER_CSC_EVOLUTIONARY_HPP_ + +#include +#include + +namespace majorminer +{ + + class CSCIndividual + { + friend EvolutionaryCSCReducer; + public: + CSCIndividual(): m_reducer(nullptr), m_done(false) {} + + void initialize(EvolutionaryCSCReducer& reducer, vertex_t sourceVertex); + + void fromInitial(const nodeset_t& placement); + bool fromCrossover(const CSCIndividual& individualA, const CSCIndividual& individualB); + void optimize(); + const nodeset_t& getSuperVertex() const { return m_superVertex; } + bool isConnected() const; + void printConnectivity() const; + + private: + void addVertex(vertex_t target); + bool tryRemove(vertex_t target); + bool tryDfsRemove(vertex_t target, fuint32_t& iteration); + void mutate(); + void reduce(); + void setupConnectivity(); + size_t getSolutionSize() const; + size_t getFitness() const; + + public: + friend bool operator<(const CSCIndividual& in1, const CSCIndividual& in2) + { + return in1.getFitness() < in2.getFitness() + || (in1.getFitness() == in2.getFitness() && in1.getSolutionSize() < in2.getSolutionSize()); + } + + private: + EvolutionaryCSCReducer* m_reducer; + const EmbeddingState* m_state; + vertex_t m_sourceVertex; + nodeset_t m_superVertex; + VertexNumberMap m_connectivity; + size_t m_fitness; + + nodeset_t m_temporarySet; + Stack m_iteratorStack; + Vector m_vertexVector; + std::unique_ptr m_random; + + bool m_done; + }; + + class EvolutionaryCSCReducer + { + friend CSCIndividual; + public: + EvolutionaryCSCReducer(EmbeddingState& state, vertex_t sourceVertex); + EvolutionaryCSCReducer(EmbeddingState& state, const nodeset_t& initial, vertex_t sourceVertex); + + void setVisualizer(EmbeddingVisualizer* vis) { m_visualizer = vis; } + void optimize(); + const nodeset_t& getPlacement() const { return m_bestSuperVertex; } + bool foundBetter() const { return m_improved; } + + private: + void initialize(); + void initialize(const nodeset_t& initial); + void setup(); + bool canExpand(); + void initializePopulations(); + void optimizeIteration(Vector& parentPopulation); + bool createNextGeneration(Vector& parentPopulation, Vector& childPopulation); + void prepareVertex(vertex_t target, nodeset_t& temp, bool count = true); + const CSCIndividual* tournamentSelection(const Vector& parentPopulation); + void visualize(fuint32_t iteration, Vector* population); + + private: // called mainly by CSCIndividual + void addConnectivity(VertexNumberMap& connectivity, nodeset_t& temp, vertex_t target); + bool isRemoveable(VertexNumberMap& connectivity, vertex_t target) const; + void removeVertex(VertexNumberMap& connectivity, vertex_t target) const; + size_t getFitness(vertex_t target) const; + size_t getFitness(const nodeset_t& placement) const; + const nodeset_t& getAdjacentSourceVertices() const { return m_adjacentSourceVertices; } + + private: + const EmbeddingState& m_state; + vertex_t m_sourceVertex; + bool m_wasPlaced; + bool m_expansionPossible; + bool m_improved; + + EmbeddingVisualizer* m_visualizer; + ThreadManager& m_threadManager; + + Vector m_populationA; + Vector m_populationB; + adjacency_list_t m_adjacentSources; + nodeset_t m_adjacentSourceVertices; + VertexNumberMap m_vertexFitness; + nodeset_t m_preparedVertices; + + nodeset_t m_bestSuperVertex; + size_t m_bestFitness; + + nodeset_t m_temporary; + RandomGen m_random; + + std::mutex m_prepareLock; + }; + +} + + + +#endif \ No newline at end of file diff --git a/src/initial/network_simplex.cpp b/src/initial/network_simplex.cpp index fbd451d..1cdf467 100644 --- a/src/initial/network_simplex.cpp +++ b/src/initial/network_simplex.cpp @@ -1,4 +1,9 @@ -#include "network_simplex.hpp" +#include "initial/network_simplex.hpp" + +#include +#include +#include +#include using namespace majorminer; @@ -6,99 +11,161 @@ using namespace majorminer; #define OCCUPIED 10 #define FREE 1 -void NetworkSimplexWrapper::embeddNode(fuint32_t node) + +NetworkSimplexWrapper::NetworkSimplexWrapper(EmbeddingState& state, EmbeddingManager& embeddingManager) + : m_state(state), m_embeddingManager(embeddingManager), m_initialized(false) +{ } + +NetworkSimplexWrapper::capacity_t NetworkSimplexWrapper::getNumberAdjacentNodes(const adjacency_list_range_iterator_t& adjacentIt) const { - auto adjacentIt = m_suite->m_source.equal_range(node); - clear(); + const auto& mapping = m_state.getMapping(); capacity_t n = 0; for (auto adjacentNode = adjacentIt.first; adjacentNode != adjacentIt.second; ++adjacentNode) { - if (m_suite->m_mapping.find(adjacentNode->second) != m_suite->m_mapping.end()) n++; + if (mapping.contains(adjacentNode->second)) n++; } - if (n < 2) throw std::runtime_error("Invalid number of embedded adjacent nodes! < 2..."); - auto lowered = n - 1; - // DEBUG(OUT_S << "Flow of " << lowered << " needed." << std::endl;) - - LemonArcMap costs(m_graph); - LemonArcMap caps(m_graph); + // if (n < 2) throw std::runtime_error("Invalid number of embedded adjacent nodes! < 2..."); + return n; +} - for (const auto& arc : *(m_suite->m_targetGraph)) +void NetworkSimplexWrapper::constructLemonGraph() +{ + // Construct base graph + const auto& targetGraph = *m_state.getTargetGraph(); + for (const auto& arc : targetGraph) { auto uNode = createNode(arc.first); auto vNode = createNode(arc.second); LemonArc uv = m_graph.addArc(uNode, vNode); LemonArc vu = m_graph.addArc(vNode, uNode); m_edgeMap.insert(std::make_pair(arc, std::make_pair(uv, vu))); - caps[uv] = lowered; - caps[vu] = lowered; - costs[uv] = determineCost(arc.first); - costs[vu] = determineCost(arc.second); } +} + +vertex_t NetworkSimplexWrapper::chooseSource(vertex_t source) const +{ + vertex_t bestFound = FUINT32_UNDEF; + m_state.iterateSourceMappingAdjacent(source, + [&](vertex_t adjacent, vertex_t){ + bestFound = adjacent; + return true; + }); + if (isDefined(bestFound)) return bestFound; + + const auto& reverse = m_state.getReverseMapping(); + const auto& remaining = m_state.getRemainingTargetNodes(); + fuint32_t numberMapped = FUINT32_UNDEF; + + m_state.iterateSourceMappingAdjacent(source, + [&](vertex_t adjacent, vertex_t){ + if (remaining.contains(adjacent)) return false; + fuint32_t nb = reverse.count(adjacent); + if (nb < numberMapped) + { + numberMapped = nb; + bestFound = adjacent; + } + return numberMapped == 1; // we can skip if we find a vertex + }); + if (!isDefined(bestFound)) throw std::runtime_error("Isolated vertex in network simplex!"); + return bestFound; +} + +NetworkSimplexWrapper::LemonNode& NetworkSimplexWrapper::getNextRootNode() +{ + if (m_rootCounter < m_rootVertices.size()) return m_rootVertices[m_rootCounter++]; + else + { + m_rootVertices.push_back(m_graph.addNode()); + LemonNode& root = m_rootVertices.back(); + createCheapArc(root, m_t, *m_costMap, *m_capMap, false); + m_rootCounter++; + return root; + } +} + +void NetworkSimplexWrapper::createCheapArc(LemonNode& from, LemonNode& to, + LemonArcMap& costs, LemonArcMap& caps, bool constructionArc, capacity_t capacity) +{ + auto temp = m_graph.addArc(from, to); + costs[temp] = 0; + caps[temp] = capacity; + if (constructionArc) m_treeConstructionArcs.push_back(temp); +} - LemonNode s = m_graph.addNode(); - LemonNode t = m_graph.addNode(); +void NetworkSimplexWrapper::constructHelperNodes(LemonArcMap& costs, LemonArcMap& caps, + const adjacency_list_range_iterator_t& adjacentIt) +{ // define nodes for construction - bool first = true; - fuint32_t sConnected = -1; + const auto& mapping = m_state.getMapping(); + + vertex_t adjacentCandidate = FUINT32_UNDEF; + + // sink vertices for (auto adjacentNode = adjacentIt.first; adjacentNode != adjacentIt.second; ++adjacentNode) { - auto embeddingPath = m_suite->m_mapping.equal_range(adjacentNode->second); + auto embeddingPath = mapping.equal_range(adjacentNode->second); if (embeddingPath.first == embeddingPath.second) continue; - if (first) - { // define s node connection - auto toNode = m_nodeMap[embeddingPath.first->second]; - sConnected = embeddingPath.first->second; - auto arc = m_graph.addArc(s, toNode); - costs[arc] = 0; - caps[arc] = lowered; - first = false; - adjustCosts(embeddingPath.first->second, costs); - continue; - } - // DEBUG(OUT_S << "Adding construction for node " << adjacentNode->second << std::endl;) - LemonNode constructionNode = m_graph.addNode(); - auto out = m_graph.addArc(constructionNode, t); - costs[out] = 0; - caps[out] = 1; + adjacentCandidate = adjacentNode->second; + + LemonNode& constructionNode = getNextRootNode(); for (auto targetNode = embeddingPath.first; targetNode != embeddingPath.second; ++targetNode) { LemonNode& fromNode = m_nodeMap[targetNode->second]; - auto temp = m_graph.addArc(fromNode, constructionNode); - costs[temp] = 0; - caps[temp] = 1; + createCheapArc(fromNode, constructionNode, costs, caps, true); } } + // source vertex + vertex_t sVertex = chooseSource(adjacentCandidate); + LemonNode& toNode = m_nodeMap[sVertex]; + m_sConnected = sVertex; + createCheapArc(m_s, toNode, costs, caps, true, m_numberAdjacent); + //adjustCosts(sVertex, costs); +} + +void NetworkSimplexWrapper::initialCreation() +{ + m_costMap = std::make_unique>(m_graph); + m_capMap = std::make_unique>(m_graph); + m_flowMap = std::make_unique>(m_graph); + constructLemonGraph(); + m_s = m_graph.addNode(); + m_t = m_graph.addNode(); + m_initialized = true; +} + +void NetworkSimplexWrapper::embeddNode(vertex_t node) +{ + if (!m_initialized) initialCreation(); + clear(); + auto adjacentIt = m_state.getSourceAdjGraph().equal_range(node); + m_numberAdjacent = getNumberAdjacentNodes(adjacentIt); + + setupCostsAndCaps(); + + constructHelperNodes(*m_costMap, *m_capMap, adjacentIt); NetworkSimplex ns(m_graph); - ns.costMap(costs).upperMap(caps).stSupply(s, t, lowered); - LemonArcMap flows(m_graph); + ns.costMap(*m_costMap).upperMap(*m_capMap).stSupply(m_s, m_t, m_numberAdjacent); NetworkSimplex::ProblemType status = ns.run(); if (status == NetworkSimplex::OPTIMAL) { - LemonArcMap flows{m_graph}; + LemonArcMap& flows = *m_flowMap; ns.flowMap(flows); - fuint32_t nbOutFlows = 0; for (const auto& arc : m_edgeMap) { - // DEBUG(OUT_S << "(" << arc.first.first << "," << arc.first.second << "): " << flows[arc.second.first] << std::endl;) - // DEBUG(OUT_S << "(" << arc.first.second << "," << arc.first.first << "): " << flows[arc.second.second] << std::endl;) if (flows[arc.second.first] > 0) { m_mapped.insert(arc.first.first); - if (arc.first.first == sConnected) nbOutFlows++; } if (flows[arc.second.second] > 0) { - if (arc.first.second == sConnected) nbOutFlows++; m_mapped.insert(arc.first.second); } } - OUT_S << "Number outflows " << nbOutFlows << std::endl; - if (nbOutFlows < 2 && m_mapped.size() > 1) m_mapped.unsafe_erase(sConnected); - m_suite->mapNode(node, m_mapped); } else if(status == NetworkSimplex::INFEASIBLE) { @@ -111,13 +178,14 @@ void NetworkSimplexWrapper::embeddNode(fuint32_t node) } -void NetworkSimplexWrapper::adjustCosts(fuint32_t node, LemonArcMap& costs) +void NetworkSimplexWrapper::adjustCosts(vertex_t node, LemonArcMap& costs) { - auto adjacentIt = m_suite->m_target.equal_range(node); + auto adjacentIt = m_state.getTargetAdjGraph().equal_range(node); + const auto& targetNodesRemaining = m_state.getRemainingTargetNodes(); for (auto it = adjacentIt.first; it != adjacentIt.second; ++it) { const auto& edges = getArcPair(node, it->second); - if (m_suite->m_targetNodesRemaining.contains(it->second)) + if (targetNodesRemaining.contains(it->second)) { costs[edges.first] = FREE; costs[edges.second] = FREE; @@ -129,7 +197,7 @@ void NetworkSimplexWrapper::adjustCosts(fuint32_t node, LemonArcMap& cos } } } -const NetworkSimplexWrapper::LemonArcPair& NetworkSimplexWrapper::getArcPair(fuint32_t n1, fuint32_t n2) +const NetworkSimplexWrapper::LemonArcPair& NetworkSimplexWrapper::getArcPair(vertex_t n1, vertex_t n2) { auto findIt = m_edgeMap.find(edge_t{n1, n2}); if (findIt != m_edgeMap.end()) @@ -139,27 +207,45 @@ const NetworkSimplexWrapper::LemonArcPair& NetworkSimplexWrapper::getArcPair(fui return m_edgeMap[edge_t{n2, n1}]; } -NetworkSimplexWrapper::LemonNode NetworkSimplexWrapper::createNode(fuint32_t node) +NetworkSimplexWrapper::LemonNode NetworkSimplexWrapper::createNode(vertex_t node) { auto findIt = m_nodeMap.find(node); if (findIt == m_nodeMap.end()) { - m_nodeMap.insert(std::make_pair(node, m_graph.addNode())); - return m_nodeMap[node]; + auto it = m_nodeMap.insert(std::make_pair(node, m_graph.addNode())); + return it.first->second; } return findIt->second; } -NetworkSimplexWrapper::cost_t NetworkSimplexWrapper::determineCost(fuint32_t node) +NetworkSimplexWrapper::cost_t NetworkSimplexWrapper::determineCost(vertex_t node) { - if (m_suite->m_nodesOccupied.contains(node)) return OCCUPIED; - return FREE; + return m_state.isNodeOccupied(node) ? OCCUPIED : FREE; +} + +void NetworkSimplexWrapper::setupCostsAndCaps() +{ + // set all costs of nonartificial arcs + for (const auto& edgePair : m_edgeMap) + { + const auto& uv = edgePair.second.first; + const auto& vu = edgePair.second.second; + (*m_capMap)[uv] = m_numberAdjacent; + (*m_capMap)[vu] = m_numberAdjacent; + (*m_costMap)[uv] = determineCost(edgePair.first.first); + (*m_costMap)[vu] = determineCost(edgePair.first.second); + } } void NetworkSimplexWrapper::clear() { - m_graph.clear(); - m_nodeMap.clear(); + for (auto& lemonArc : m_treeConstructionArcs) + { + (*m_capMap)[lemonArc] = 0; + } m_mapped.clear(); - m_edgeMap.clear(); + m_numberAdjacent = 0; + m_sConnected = -1; + + m_rootCounter = 0; } diff --git a/src/initial/network_simplex.hpp b/src/initial/network_simplex.hpp index 61b88be..fe066ce 100644 --- a/src/initial/network_simplex.hpp +++ b/src/initial/network_simplex.hpp @@ -4,13 +4,10 @@ #include #include -#include "majorminer_types.hpp" -#include "majorminer.hpp" +#include namespace majorminer { - class EmbeddingSuite; - class NetworkSimplexWrapper { using cost_t = int; @@ -22,25 +19,58 @@ namespace majorminer using LemonArcMap = LemonGraph::ArcMap; using NetworkSimplex = lemon::NetworkSimplex; typedef std::pair LemonArcPair; + public: - NetworkSimplexWrapper(EmbeddingSuite* suite) - : m_suite(suite) { } + NetworkSimplexWrapper(EmbeddingState& state, EmbeddingManager& embeddingManager); - void embeddNode(fuint32_t node); + void embeddNode(vertex_t node); + const nodeset_t& getMapped() const { return m_mapped; } private: - LemonNode createNode(fuint32_t node); - cost_t determineCost(fuint32_t node); - void adjustCosts(fuint32_t node, LemonArcMap& costs); + void initialCreation(); + LemonNode createNode(vertex_t node); + cost_t determineCost(vertex_t node); + void adjustCosts(vertex_t node, LemonArcMap& costs); + void setupCostsAndCaps(); + + const LemonArcPair& getArcPair(vertex_t n1, vertex_t n2); + vertex_t chooseSource(vertex_t source) const; + + void createCheapArc(LemonNode& from, LemonNode& to, LemonArcMap& costs, + + LemonArcMap& caps, bool constructionArc = false, capacity_t capacity = 1); + + capacity_t getNumberAdjacentNodes(const adjacency_list_range_iterator_t& adjacentIt) const; + void constructLemonGraph(); + void constructHelperNodes(LemonArcMap& costs, LemonArcMap& caps, + const adjacency_list_range_iterator_t& adjacentIt); + + LemonNode& getNextRootNode(); void clear(); - const LemonArcPair& getArcPair(fuint32_t n1, fuint32_t n2); private: LemonGraph m_graph; - EmbeddingSuite* m_suite; - UnorderedMap m_nodeMap; - UnorderedMap> m_edgeMap; - UnorderedSet m_mapped; + EmbeddingState& m_state; + EmbeddingManager& m_embeddingManager; + UnorderedMap m_nodeMap; + UnorderedMap> m_edgeMap; + UnorderedSet m_mapped; + + std::unique_ptr> m_costMap; + std::unique_ptr> m_capMap; + std::unique_ptr> m_flowMap; + + Vector m_rootVertices; + Vector m_treeConstructionArcs; + + LemonNode m_s; + LemonNode m_t; + + capacity_t m_numberAdjacent; + fuint32_t m_sConnected; + fuint32_t m_rootCounter; + + bool m_initialized; }; } diff --git a/src/initial/super_vertex_placer.cpp b/src/initial/super_vertex_placer.cpp new file mode 100644 index 0000000..9ccc9e4 --- /dev/null +++ b/src/initial/super_vertex_placer.cpp @@ -0,0 +1,247 @@ +#include "super_vertex_placer.hpp" + +#include "super_vertex_reducer.hpp" + +#include +#include +#include +#include +#include +#include +#include + +using namespace majorminer; + +SuperVertexPlacer::SuperVertexPlacer(EmbeddingState& state, EmbeddingManager& embeddingManager) + : m_state(state), m_embeddingManager(embeddingManager) +{} + +void SuperVertexPlacer::operator()() +{ + if (!m_nodesToProcess.empty()) + { + if (!connectedNode()) return; + } + else + { + trivialNode(); + } +} + +void SuperVertexPlacer::replaceOverlapping() +{ + std::cout << "Replace overlapping " << std::endl; + nodeset_t overlapping{}; + fuint32_t maxIterations = 5; + // const auto& sourceGraph = m_state.getSourceAdjGraph(); + + // nodeset_t temporary{}; + + for (fuint32_t idx = 0; idx < maxIterations; ++idx) + { + identifyOverlapping(overlapping); + if (overlapping.empty()) break; + std::cout << "Replace overlapping; iteration " << (idx + 1) << std::endl; + for (vertex_t vertex : overlapping) + { + improveMapping(vertex); + // replaceSuperVertex(vertex, temporary); + + // visualize(vertex, PlacedNodeType::COMPLEX, sourceGraph.count(vertex)); + } + + } +} + + +void SuperVertexPlacer::identifyOverlapping(nodeset_t& overlapping) +{ + overlapping.clear(); + const auto& reverse = m_state.getReverseMapping(); + fuint32_pair_t lastPair = std::make_pair(FUINT32_UNDEF, FUINT32_UNDEF); + for (auto reverseMapped : reverse) + { + if (isDefined(lastPair.first) && lastPair.first == reverseMapped.first) + { // overlapping + overlapping.insert(lastPair.second); + overlapping.insert(reverseMapped.second); + } + lastPair = reverseMapped; + } +} + +void SuperVertexPlacer::improveMapping(vertex_t source) +{ + EvolutionaryCSCReducer reducer{m_state, source}; + const auto& sourceGraph = m_state.getSourceAdjGraph(); + reducer.optimize(); + if (reducer.foundBetter()) + { + m_embeddingManager.unmapNode(source); + const auto& superVertex = reducer.getPlacement(); + m_embeddingManager.mapNode(source, superVertex); + std::cout << "Improved through reducer. " << std::endl; + if (m_state.hasVisualizer()) + { + visualize(source, PlacedNodeType::COMPLEX, sourceGraph.count(source)); + } + } +} + +void SuperVertexPlacer::trivialNode() +{ + // just pick an arbitrary node and place it somewhere + vertex_t node = m_state.getTrivialNode(); + // DEBUG(OUT_S << "Trivial node to embedd: " << node << std::endl;) + embeddTrivialNode(node); + + if (m_state.hasVisualizer()) visualize(node, TRIVIAL); +} + +bool SuperVertexPlacer::connectedNode() +{ + PrioNode node = m_nodesToProcess.top(); + m_nodesToProcess.pop(); + + if (!m_state.removeRemainingNode(node.m_id)) return false; + + + if (node.m_nbConnections > 1) + { + embeddNode(node.m_id); + if (m_state.hasVisualizer()) visualize(node.m_id, COMPLEX, node.m_nbConnections); + } + else + { // nbConnections = 1 + embeddSimpleNode(node.m_id); + m_state.updateConnections(node.m_id, m_nodesToProcess); + + if (m_state.hasVisualizer()) visualize(node.m_id, SIMPLE); + } + return true; +} + +void SuperVertexPlacer::embeddNode(vertex_t node) +{ + embeddNodeNetworkSimplex(node); + m_state.updateConnections(node, m_nodesToProcess); +} + + + +void SuperVertexPlacer::visualize(vertex_t node, PlacedNodeType type, fuint32_t nbConnections) +{ + auto& visualizer = *m_state.getVisualizer(); + const auto& mapping = m_state.getMapping(); + switch(type) + { + case TRIVIAL: + { + visualizer.draw(mapping, + [&](std::ostream& os) + { os << "Trivial node " << node; } + ); + break; + } + case SIMPLE: + { + visualizer.draw(mapping, + [&](std::ostream &os) + { os << "Simple adjacent node " << node << " (1)."; } + ); + break; + } + case COMPLEX: + { + visualizer.draw(mapping, + [&](std::ostream &os) + { os << "Complex adjacent node " << node + << " (" << nbConnections << ")"; } + ); + break; + } + } +} + +void SuperVertexPlacer::replaceSuperVertex(vertex_t source, nodeset_t& svertex) +{ + svertex.clear(); + m_state.iterateSourceMapping(source, [&](vertex_t target) { svertex.insert(target); }); + m_embeddingManager.unmapNode(source); + embeddNodeNetworkSimplex(source, &svertex); +} + + +void SuperVertexPlacer::embeddNodeNetworkSimplex(vertex_t node, const nodeset_t* oldMapping) +{ + if (m_nsWrapper.get() == nullptr) m_nsWrapper = std::make_unique(m_state, m_embeddingManager); + m_nsWrapper->embeddNode(node); + + SuperVertexReducer reducer{m_state, node}; + reducer.initialize(m_nsWrapper->getMapped()); + reducer.optimize(); + const auto& superVertex = reducer.getBetterPlacement(m_nsWrapper->getMapped()); + fuint32_t fitness = calculateFitness(m_state, superVertex); + if (oldMapping == nullptr) + { + m_embeddingManager.mapNode(node, superVertex); + return; + } + fuint32_t oldFitness = calculateFitness(m_state, *oldMapping); + if (std::make_pair(fitness, superVertex.size()) < std::make_pair(oldFitness, oldMapping->size())) + { + m_embeddingManager.mapNode(node, superVertex); + } + else m_embeddingManager.mapNode(node, *oldMapping); + + /*EvolutionaryCSCReducer reducer{m_state, m_nsWrapper->getMapped(), node}; + reducer.optimize(); + const auto& superVertex = reducer.getPlacement(); + m_embeddingManager.mapNode(node, superVertex); + printNodeset(m_nsWrapper->getMapped()); + printNodeset(superVertex);*/ + +} + +void SuperVertexPlacer::embeddSimpleNode(vertex_t node) +{ + // find a node that is adjacent to the node "adjacentNode" + vertex_t adjacentNode = -1; + m_state.iterateSourceGraphAdjacentBreak(node, [&](vertex_t adjacent){ + if (m_state.isNodeMapped(adjacent)) + { adjacentNode = adjacent; return true; } + return false; + }); + + if (adjacentNode == (fuint32_t)-1) throw std::runtime_error("Could not find the adjacent node."); + + const auto& remaining = m_state.getRemainingTargetNodes(); + vertex_t bestNodeFound = FUINT32_UNDEF; + m_state.iterateSourceMappingAdjacent(adjacentNode, + [&bestNodeFound, &remaining](vertex_t candidate, vertex_t){ + bestNodeFound = candidate; + return remaining.contains(candidate); + }); + if (!isDefined(bestNodeFound)) throw std::runtime_error("Isolated vertex."); + + // map "node" to "bestNodeFound" + m_embeddingManager.mapNode(node, bestNodeFound); + m_state.updateNeededNeighbors(node); +} + +void SuperVertexPlacer::embeddTrivialNode(vertex_t node) +{ + auto& remainingTargetNodes = m_state.getRemainingTargetNodes(); + if (!remainingTargetNodes.empty()) + { + auto targetNode = *remainingTargetNodes.begin(); + remainingTargetNodes.unsafe_erase(remainingTargetNodes.begin()); + m_embeddingManager.mapNode(node, targetNode); + m_state.updateNeededNeighbors(node); + m_state.updateConnections(node, m_nodesToProcess); + } + else + { + throw std::runtime_error("Oooops..."); + } +} diff --git a/src/initial/super_vertex_placer.hpp b/src/initial/super_vertex_placer.hpp new file mode 100644 index 0000000..fc05fbb --- /dev/null +++ b/src/initial/super_vertex_placer.hpp @@ -0,0 +1,49 @@ +#ifndef __MAJORMINER_SUPER_VERTEX_PLACER_HPP_ +#define __MAJORMINER_SUPER_VERTEX_PLACER_HPP_ + +#include +#include + +namespace majorminer +{ + class SuperVertexPlacer + { + enum PlacedNodeType + { + TRIVIAL, SIMPLE, COMPLEX + }; + public: + SuperVertexPlacer(EmbeddingState& state, EmbeddingManager& embeddingManager); + + void operator()(); + void replaceOverlapping(); + + private: + void identifyOverlapping(nodeset_t& overlapping); + void improveMapping(vertex_t source); + void trivialNode(); + bool connectedNode(); + void replaceSuperVertex(vertex_t source, nodeset_t& svertex); + + void embeddNode(vertex_t node); + void embeddNodeNetworkSimplex(vertex_t node, const nodeset_t* oldMapping = nullptr); + + void embeddTrivialNode(vertex_t node); + void embeddSimpleNode(vertex_t node); + + void visualize(vertex_t node, PlacedNodeType type, fuint32_t nbConnections = 0); + + private: + EmbeddingState& m_state; + EmbeddingManager& m_embeddingManager; + + PrioNodeQueue m_nodesToProcess; + + std::unique_ptr m_nsWrapper; + }; + +} + + + +#endif \ No newline at end of file diff --git a/src/initial/super_vertex_reducer.cpp b/src/initial/super_vertex_reducer.cpp new file mode 100644 index 0000000..734c5e5 --- /dev/null +++ b/src/initial/super_vertex_reducer.cpp @@ -0,0 +1,217 @@ +#include "super_vertex_reducer.hpp" + +#include +#include +#include +#include +#include + +using namespace majorminer; + +SuperVertexReducer::SuperVertexReducer(const EmbeddingBase& base, vertex_t sourceVertex) + : m_embedding(base), m_sourceVertex(sourceVertex), m_done(false) +{ } + +void SuperVertexReducer::setup() +{ + // prepare m_potentialNodes + m_potentialNodes.insert(m_superVertex.begin(), m_superVertex.end()); + const auto& remaining = m_embedding.getRemainingTargetNodes(); + for (auto mapped : m_superVertex) + { + m_embedding.iterateTargetGraphAdjacent(mapped, [&](vertex_t targetAdj){ + if (remaining.contains(targetAdj)) m_potentialNodes.insert(targetAdj); + }); + } + + if (!acceptOnlyReduction && (m_potentialNodes.size() == m_superVertex.size() || m_potentialNodes.size() <= 1)) + { + m_done = true; + return; + } + + // prepare source vertices in m_sourceConnections + const auto& mapping = m_embedding.getMapping(); + m_embedding.iterateSourceGraphAdjacent(m_sourceVertex, + [&](vertex_t adjacent){ + if (mapping.contains(adjacent)) m_sourceConnections[adjacent] = 0; + }); + + // prepare m_adjacencies + m_verticesList = std::make_unique(m_potentialNodes.size()); + nodepairset_t adjacentSource; + fuint32_t idx = 0; + for (auto node : m_potentialNodes) + { + m_verticesList[idx++] = node; + m_embedding.iterateTargetAdjacentReverseMapping(node, [&](vertex_t adjSource){ + if (m_sourceConnections.contains(adjSource)) adjacentSource.insert(std::make_pair(node, adjSource)); + }); + } + for (auto& adj : adjacentSource) m_adjacencies.insert(adj); + + // prepare m_sourceConnections + for (const auto& adj : m_adjacencies) + { + if (m_superVertex.contains(adj.first)) m_sourceConnections[adj.second]++; + } +} + +void SuperVertexReducer::initialize(const nodeset_t& currentMapping) +{ + const auto& mapping = m_embedding.getMapping(); + if (mapping.find(m_sourceVertex) != mapping.end()) + { + throw std::runtime_error("Not a temporary mapping. Vertex was already mapped!"); + } + m_superVertex.insert(currentMapping.begin(), currentMapping.end()); + setup(); +} + +void SuperVertexReducer::initialize() +{ + clear(); + const auto& mapping = m_embedding.getMapping(); + auto range = mapping.equal_range(m_sourceVertex); + for (auto it = range.first; it != range.second; ++it) + { + m_superVertex.insert(it->second); + } + m_initialSuperVertex.insert(m_superVertex.begin(), m_superVertex.end()); + acceptOnlyReduction = true; + setup(); +} + +void SuperVertexReducer::clear() +{ + m_initialSuperVertex.clear(); + m_superVertex.clear(); + m_potentialNodes.clear(); + m_adjacencies.clear(); + m_sourceConnections.clear(); + m_done = false; +} + +void SuperVertexReducer::optimize() +{ + if (m_done) return; + RandomGen rand{}; + m_rand = &rand; + fuint32_t maxIters = 8 * m_potentialNodes.size(); + fuint32_t halfMax = maxIters / 2; + fuint32_t iteration = 0; + for (; iteration < halfMax; ++iteration) + { + fuint32_t flipIdx = rand.getRandomUint(m_potentialNodes.size() - 1); + vertex_t target = m_verticesList[flipIdx]; + if (m_superVertex.contains(target)) removeNode(target); + else addNode(target); + } + + for (auto& node : m_potentialNodes) + { + if (m_superVertex.contains(node) && isBadNode(node)) + { + removeNode(node); + } + } + + for (; iteration < maxIters && m_superVertex.size() > 1; ++iteration) + { + fuint32_t flipIdx = rand.getRandomUint(m_potentialNodes.size() - 1); + vertex_t target = m_verticesList[flipIdx]; + if (m_superVertex.contains(target)) removeNode(target); + } + + for (fuint32_t idx = 0; idx < m_potentialNodes.size(); ++idx) + { + if (m_superVertex.contains(m_verticesList[idx])) removeNode(m_verticesList[idx]); + } + + m_done = true; +} + +bool SuperVertexReducer::isBadNode(fuint32_t target) const +{ + bool initial = m_initialSuperVertex.contains(target); + size_t count = m_embedding.getReverseMapping().count(target); + return count >= (initial ? 2 : 1); +} + +void SuperVertexReducer::addNode(fuint32_t target) +{ + if (m_superVertex.contains(target) || isBadNode(target) || !isConnected(target)) return; + + m_superVertex.insert(target); + auto range = m_adjacencies.equal_range(target); + for (auto it = range.first; it != range.second; ++it) + { + m_sourceConnections[it->second]++; + } +} + +void SuperVertexReducer::removeNode(fuint32_t target) +{ + if (!m_superVertex.contains(target)) return; + // 1. Check whether for each adjacent source vertex, there is another adjacent target node + auto range = m_adjacencies.equal_range(target); + + for (auto it = range.first; it != range.second; ++it) + { + if (m_sourceConnections[it->second] <= 1) return; + } + + // 2. Check whether cut vertex + nodeset_t temp {}; + temp.insert(m_superVertex.begin(), m_superVertex.end()); + if (isCutVertex(m_embedding, temp, target)) return; + + // Now remove the vertex + m_superVertex.unsafe_erase(target); + for (auto it = range.first; it != range.second; ++it) + { + m_sourceConnections[it->second]--; + } +} + +bool SuperVertexReducer::isConnected(fuint32_t target) const +{ + bool connected = false; + m_embedding.iterateTargetGraphAdjacentBreak(target, [&](fuint32_t adj){ + connected |= m_superVertex.contains(adj); + return connected; + }); + return connected; +} + +fuint32_t SuperVertexReducer::checkScore(const nodeset_t& placement) const +{ + fuint32_t numberBad = 0; + for (auto node : placement) if (isBadNode(node)) numberBad++; + return numberBad; +} + +const nodeset_t& SuperVertexReducer::getBetterPlacement(const nodeset_t& previous) const +{ + fuint32_t scorePrevious = checkScore(previous); + fuint32_t scoreOwn = checkScore(m_superVertex); + return (scorePrevious < scoreOwn || (scorePrevious == scoreOwn && previous.size() < m_superVertex.size())) + ? previous : m_superVertex; +} + +bool SuperVertexReducer::improved() const +{ + // printNodeset(m_initialSuperVertex); + // printNodeset(m_superVertex); + fuint32_t scorePrevious = checkScore(m_initialSuperVertex); + fuint32_t scoreOwn = checkScore(m_superVertex); + return (scoreOwn < scorePrevious || + (scorePrevious == scoreOwn && m_superVertex.size() < m_initialSuperVertex.size())); +} + +bool SuperVertexReducer::remainsValid(const EmbeddingManager& manager) const +{ + // m_superVertex is definitely connected, now check whether all + // adjacent super vertices can be reached + return improved() && connectsToAdjacentVertices(manager, m_superVertex, m_sourceVertex); +} \ No newline at end of file diff --git a/src/initial/super_vertex_reducer.hpp b/src/initial/super_vertex_reducer.hpp new file mode 100644 index 0000000..4e649f5 --- /dev/null +++ b/src/initial/super_vertex_reducer.hpp @@ -0,0 +1,58 @@ +#ifndef __MAJORMINER_SUPER_VERTEX_REDUCER_HPP_ +#define __MAJORMINER_SUPER_VERTEX_REDUCER_HPP_ + +#include + +namespace majorminer +{ + + class SuperVertexReducer + { + public: + SuperVertexReducer(const EmbeddingBase& base, fuint32_t sourceVertex); + + void optimize(); + const nodeset_t& getSuperVertex() const { return m_superVertex; } + const nodeset_t& getInitialSuperVertex() const { return m_initialSuperVertex; } + void initialize(); + void initialize(const nodeset_t& currentMapping); + const nodeset_t& getBetterPlacement(const nodeset_t& previous) const; + bool improved() const; + + // Checks whether the solution is valid even on the embedding managers data + bool remainsValid(const EmbeddingManager& manager) const; + + private: + void clear(); + void setup(); + bool isBadNode(fuint32_t target) const; + void addNode(fuint32_t target); + void removeNode(fuint32_t target); + fuint32_t checkScore(const nodeset_t& placement) const; + + // checks whether a new target node would be connected to the super vertex + bool isConnected(fuint32_t target) const; + + private: + const EmbeddingBase& m_embedding; + nodeset_t m_initialSuperVertex; + nodeset_t m_superVertex; // current super vertex + nodeset_t m_potentialNodes; + adjacency_list_t m_adjacencies; // (targetVertex, adjacentSource) + fuint32_t m_sourceVertex; + + std::unique_ptr m_verticesList; + + RandomGen* m_rand; + + bool acceptOnlyReduction = false; + + // for each neighbor of m_sourceVertex, map contains the number of + // vertices of m_sourceVertex connecting the two + UnorderedMap m_sourceConnections; + bool m_done; + }; + +} + +#endif diff --git a/src/lmrp/CMakeLists.txt b/src/lmrp/CMakeLists.txt new file mode 100644 index 0000000..d7c6942 --- /dev/null +++ b/src/lmrp/CMakeLists.txt @@ -0,0 +1,7 @@ + +target_sources(majorminer PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/lmrp_types.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/lmrp_chimera_subgraph.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/lmrp_king_subgraph.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/lmrp_heuristic.cpp +) diff --git a/src/lmrp/lmrp_chimera_subgraph.cpp b/src/lmrp/lmrp_chimera_subgraph.cpp new file mode 100644 index 0000000..81d85c3 --- /dev/null +++ b/src/lmrp/lmrp_chimera_subgraph.cpp @@ -0,0 +1,71 @@ +#include "lmrp_chimera_subgraph.hpp" + +using namespace majorminer; + + +bool ChimeraLMRPSubgraph::getSubgraph(vertex_t contained, nodeset_t& subgraph) +{ + fuint32_t x = m_graph.getXCoord(contained); + fuint32_t y = m_graph.getYCoord(contained); + m_updateLock.lock(); + bool success = !checkOccupation(x, y, contained); + if (success) + { + neighborhood(x,y,contained, + [&](const fuint32_pair_t& pair, bool inCrater){ + if (inCrater) m_occupied.insert(pair); + }); + } + m_updateLock.unlock(); + if (success) + { + subgraph.clear(); + fuint32_t width = m_graph.getWidth(); + neighborhood(x,y,contained, + [&](const fuint32_pair_t& pair, bool inCrater){ + if (inCrater) // pair := (x_coord, y_coord) + { + fuint32_t base = (width * pair.second + pair.first) * 8; + for (fuint32_t i = 0; i < 8; ++i) + { + subgraph.insert(base + i); + } + } + }); + } + return success; +} + +bool ChimeraLMRPSubgraph::isBeingDestroyed(vertex_t contained) +{ + fuint32_t x = m_graph.getXCoord(contained); + fuint32_t y = m_graph.getYCoord(contained); + + m_updateLock.lock_shared(); + bool occupied = checkOccupation(x, y, contained); + m_updateLock.unlock_shared(); + + return occupied; +} + +bool ChimeraLMRPSubgraph::checkOccupation(fuint32_t x, fuint32_t y, vertex_t contained) const +{ + bool occupied = false; + neighborhood(x,y, contained, + [&](const fuint32_pair_t& pair, bool){ + occupied |= m_occupied.contains(pair); + }); + return occupied; +} + +void ChimeraLMRPSubgraph::commit(vertex_t contained) +{ + fuint32_t x = m_graph.getXCoord(contained); + fuint32_t y = m_graph.getYCoord(contained); + m_updateLock.lock(); + neighborhood(x,y,contained, + [&](const fuint32_pair_t& pair, bool inCrater){ + if (inCrater) m_occupied.unsafe_erase(pair); + }); + m_updateLock.unlock(); +} diff --git a/src/lmrp/lmrp_chimera_subgraph.hpp b/src/lmrp/lmrp_chimera_subgraph.hpp new file mode 100644 index 0000000..64d706c --- /dev/null +++ b/src/lmrp/lmrp_chimera_subgraph.hpp @@ -0,0 +1,62 @@ +#ifndef __MAJORMINER_LMRP_CHIMERA_SUBGRAPH_HPP_ +#define __MAJORMINER_LMRP_CHIMERA_SUBGRAPH_HPP_ + +#include +#include +#include + +namespace majorminer +{ + + class ChimeraLMRPSubgraph : public LMRPSubgraph + { + public: + ChimeraLMRPSubgraph(ChimeraGraphInfo& g): m_graph(g) {} + ~ChimeraLMRPSubgraph() {} + + bool getSubgraph(vertex_t contained, nodeset_t& subgraph) override; + + bool isBeingDestroyed(vertex_t contained) override; + + // If a LMRP instance was solved, free the mapped vertices + void commit(vertex_t contained) override; + + private: + bool checkOccupation(fuint32_t x, fuint32_t y, vertex_t contained) const; + + template + void neighborhood(fuint32_t x, fuint32_t y, vertex_t contained, Functor func) const + { + bool leftSide = (contained & 0x04) == 0; + auto width = m_graph.getWidth(); + auto height = m_graph.getHeight(); + + fuint32_t minX = static_cast(std::max(static_cast(x) - (leftSide ? 2 : 1), 0)); + fuint32_t maxX = std::min(x + (leftSide ? 2 : 3), width); + fuint32_t minY = y > 0 ? (y - 1) : 0; + fuint32_t maxY = std::min(y + 3, height); + + fuint32_t otherX = (!leftSide ? (x + 1) : (x > 0 ? x - 1 : FUINT32_UNDEF)); + + for (fuint32_t itX = minX; itX < maxX; ++itX) + { + for (fuint32_t itY = minY; itY < maxY; ++itY) + { + bool craterY = (itY == y || itY == y + 1); + bool isInCrater = craterY && (itX == x || itX == otherX); + func(fuint32_pair_t{itX, itY}, isInCrater); + } + } + } + + private: + ChimeraGraphInfo m_graph; + coordinateset_t m_occupied; + + std::shared_mutex m_updateLock; + }; + +} + + +#endif \ No newline at end of file diff --git a/src/lmrp/lmrp_heuristic.cpp b/src/lmrp/lmrp_heuristic.cpp new file mode 100644 index 0000000..7a0d36c --- /dev/null +++ b/src/lmrp/lmrp_heuristic.cpp @@ -0,0 +1,591 @@ +#include + +#include +#include +#include + +using namespace majorminer; + + +LMRPHeuristic::LMRPHeuristic(EmbeddingState& state, vertex_t target) + : m_state(state), m_done(false), m_numberOverlaps(0), + m_numberMapped(0), m_currentSource(0) +{ + LMRPSubgraph* gen = state.getSubgraphGen(); + if (gen != nullptr) + { + bool success = gen->getSubgraph(target, m_crater); + // std::cout << "Success in subgraph " << success << std::endl; + // TODO: commit once done! + if (!success) m_done = true; + } + else m_done = true; +} + + +void LMRPHeuristic::optimize() +{ + if (m_done) return; + calculatePreviousFitness(); + buildBorder(); + printNodeset(m_crater); + printNodeset(m_border); + identifyEdges(); + identifyComponents(); + identifyDestroyed(); + printAdjacencyList(m_sourceAdjacencies); + + initializeDijkstraData(); + solve(); +} + +void LMRPHeuristic::buildBorder() +{ + for (vertex_t target : m_crater) + { + m_state.iterateTargetGraphAdjacent(target, + [&](vertex_t targetAdj){ + if (!m_crater.contains(targetAdj)) m_border.insert(targetAdj); + }); + } +} + +// identify all edges of the source graph embedded in m_crater +void LMRPHeuristic::identifyEdges() +{ + identifyEdgesFrom(m_crater); + identifyEdgesFrom(m_border); + + convertToAdjacencyList(m_sourceAdjacencies, m_edges); +} + +void LMRPHeuristic::identifyEdgesFrom(const nodeset_t& from) +{ + const auto& sourceGraph = *m_state.getSourceGraph(); + const auto& targetGraph = *m_state.getTargetGraph(); + const auto& reverse = m_state.getReverseMapping(); + for (auto itA = from.begin(); itA != from.end(); ++itA) + { + for (auto itB = m_crater.begin(); itB != m_crater.end(); ++itB) + { + if (*itB == *itA) continue; + else if (containsEdge(targetGraph, edge_t{*itA, *itB})) + { + auto rangeA = reverse.equal_range(*itA); + for (auto revA = rangeA.first; revA != rangeA.second; ++revA) + { + auto rangeB = reverse.equal_range(*itB); + for (auto revB = rangeB.first; revB != rangeB.second; ++revB) + { + edge_t edge{revA->second, revB->second}; + if (containsEdge(sourceGraph, edge)) + { + m_edges.insert(orderedPair(edge)); + } + } + } + } + } + } +} + +void LMRPHeuristic::identifyComponents() +{ + const auto& targetGraph = m_state.getTargetAdjGraph(); + + graph_t borderMapped{}; + graph_t subgraph{}; + buildSubgraphs(borderMapped, subgraph); + + + Stack dfsStack{}; + Stack currentReachable{}; + vertex_t source; + while(!borderMapped.empty()) + { + auto& startVertex = *borderMapped.begin(); + dfsStack.push(targetGraph.equal_range(startVertex.first)); + source = startVertex.second; + currentReachable.push(startVertex.first); + subgraph.unsafe_erase(startVertex); + borderMapped.unsafe_erase(startVertex); + + // Conduct DFS + while(!dfsStack.empty()) + { + if (empty_range(dfsStack.top())) dfsStack.pop(); + else + { + vertex_t neighbor = dfsStack.top().first->second; + dfsStack.top().first++; + edge_t mapped{neighbor, source}; + if (!subgraph.contains(mapped)) continue; + dfsStack.push(targetGraph.equal_range(neighbor)); + if (borderMapped.contains(mapped)) currentReachable.push(neighbor); + subgraph.unsafe_erase(mapped); + borderMapped.unsafe_erase(mapped); + } + } + + // Use the DFS results (i. e. currentReachable for source) + m_componentsList.push_back(ConnectedList{source, + m_componentVertices.size(), currentReachable.size()}); + while(!currentReachable.empty()) + { + m_componentVertices.push_back(currentReachable.top()); + currentReachable.pop(); + } + } +} + +void LMRPHeuristic::buildSubgraphs(graph_t& borderMapped, graph_t& subgraph) +{ + const auto& reverse = m_state.getReverseMapping(); + for (auto borderVertex : m_border) + { + auto range = reverse.equal_range(borderVertex); + for (auto it = range.first; it != range.second; ++it) + { + borderMapped.insert(*it); + } + } + subgraph.insert(borderMapped.begin(), borderMapped.end()); + for (auto craterVertex : m_crater) + { + auto range = reverse.equal_range(craterVertex); + for (auto it = range.first; it != range.second; ++it) + { + subgraph.insert(*it); + } + } +} + +void LMRPHeuristic::calculatePreviousFitness() +{ + const auto& reverse = m_state.getReverseMapping(); + for (vertex_t target : m_crater) + { + fuint32_t count = reverse.count(target); + if (count > 0) m_numberMapped++; + if (count > 1) m_numberOverlaps += (count - 1); + } +} + +void LMRPHeuristic::identifyDestroyed() +{ + for (auto target : m_crater) + { + m_state.iterateReverseMapping(target, + [&](vertex_t source){ + m_completelyDestroyed.insert(source); + }); + } + for (const auto& component : m_componentsList) + { + m_completelyDestroyed.unsafe_erase(component.m_source); + } +} + +void LMRPHeuristic::solve() +{ + std::sort(m_componentsList.begin(), m_componentsList.end()); + fuint32_t idx = 0; + for (auto& component : m_componentsList) + { + m_currentSource = component.m_source; + if (component.m_nbMapped > 1) + { + connectComponent(component, idx); + } + idx++; + } + + idx = 0; + for (auto& component : m_componentsList) + { + if (!component.wasSatisfied()) connectComponent(component, idx); + idx++; + } + + embeddDestroyed(); +} + +void LMRPHeuristic::initializeDijkstraData() +{ + for (vertex_t target : m_crater) + { + m_bestPaths[target] = DijkstraVertex{target}; + } +} + +void LMRPHeuristic::resetDijkstra() +{ + for (auto& vertex : m_bestPaths) vertex.second.reset(); + while(!m_dijkstraQueue.empty()) m_dijkstraQueue.pop(); +} + +void LMRPHeuristic::connectComponent(ConnectedList& component, fuint32_t componentIdx) +{ + if (component.m_nbMapped == 0) return; + vertex_t root = m_componentVertices[component.m_idx]; + m_currentSource = component.m_source; + + nodeset_t toConnect{}; + if (component.m_nbMapped > 1) + { // connect the component itself + for (fuint32_t offset = 1; offset < component.m_nbMapped; ++offset) + { + toConnect.insert(m_componentVertices[component.m_idx + offset]); + } + while(!toConnect.empty()) + { + runDijkstraToTarget(toConnect, root); + } + } + if (componentIdx == m_componentsList.size() || + m_componentsList[componentIdx + 1].m_source != component.m_source) + { + // embedd all edges + toConnect.clear(); + auto adjRange = m_sourceAdjacencies.equal_range(m_currentSource); + for (auto adjIt = adjRange.first; adjIt != adjRange.second; ++adjIt) + { + if (m_mapping.contains(adjIt->second)) toConnect.insert(adjIt->second); + } + + auto mappedRange = m_mapping.equal_range(m_currentSource); + for (auto mapped = mappedRange.first; mapped != mappedRange.second; ++mapped) + { // check for every within crater whether already connected to adjacent + checkConnectedToSource(toConnect, mapped->second); + } + + while(!toConnect.empty()) + { + connectAdjacentComponents(toConnect); + } + } + component.satisfied(); + +} + +void LMRPHeuristic::addBorderToMapping() +{ + const auto& reverse = m_state.getReverseMapping(); + for (auto borderVertex : m_border) + { + auto mappedRange = reverse.equal_range(borderVertex); + for (auto revIt = mappedRange.first; revIt != mappedRange.second; ++revIt) + { + mapVertex(revIt->second, revIt->first); + } + m_reverse.insert(mappedRange.first, mappedRange.second); + } +} + +fuint32_pair_t LMRPHeuristic::getLeastMappedNeighbor(vertex_t source) +{ + vertex_t neighbor = FUINT32_UNDEF; + fuint32_t connectivity = FUINT32_UNDEF; + fuint32_t numberMappedNeighbors = 0; + + auto range = m_sourceAdjacencies.equal_range(source); + for (auto mappedIt = range.first; mappedIt != range.second; ++mappedIt) + { + fuint32_t count = m_mapping.count(mappedIt->second); + if (count > 0 && count < connectivity) + { + numberMappedNeighbors++; + connectivity = count; + neighbor = mappedIt->second; + } + } + return std::make_pair(neighbor, numberMappedNeighbors); +} + +void LMRPHeuristic::embeddDestroyed() +{ + addBorderToMapping(); + + for (vertex_t destroyed : m_completelyDestroyed) + { + embeddSingleDestroyed(destroyed); + } +} + +void LMRPHeuristic::mapToFreeVertex() +{ + vertex_t bestFound = FUINT32_UNDEF; + fuint32_t count = FUINT32_UNDEF; + + for (auto target : m_crater) + { + fuint32_t c = m_reverse.count(target); + if (c < count) + { + count = c; + bestFound = target; + if (c == 0) break; + } + } + if (isDefined(count)) mapVertex(m_currentSource, bestFound); + else throw std::runtime_error("Error in LMRP heuristic!"); +} + +void LMRPHeuristic::mapToSingleAdjacent(vertex_t neighbor) +{ + vertex_t bestFound = FUINT32_UNDEF; + fuint32_t count = FUINT32_UNDEF; + + auto mappedRange = m_mapping.equal_range(neighbor); + for (auto mappedIt = mappedRange.first; mappedIt != mappedRange.second; ++mappedIt) + { + m_state.iterateTargetGraphAdjacent(mappedIt->second, + [&](fuint32_t adjTarget){ + if (m_crater.contains(adjTarget)) + { + fuint32_t c = m_reverse.count(adjTarget); + if (c < count) + { + count = c; + bestFound = adjTarget; + } + } + }); + if (count == 0) break; + } + if (isDefined(count)) mapVertex(m_currentSource, bestFound); + else throw std::runtime_error("Error in LMRP heuristic!"); +} + +void LMRPHeuristic::embeddSingleDestroyed(vertex_t source) +{ + m_currentSource = source; + auto neighbor = getLeastMappedNeighbor(source); + if (neighbor.second == 0) mapToFreeVertex(); + else if (neighbor.second == 1) + { + mapToSingleAdjacent(neighbor.first); + m_edges.unsafe_erase(orderedPair(source, neighbor.first)); + } + else dijkstraDestroyed(source, neighbor.first); +} + +void LMRPHeuristic::addAdjacentVertices(vertex_t source, nodeset_t& adjacent) +{ + auto range = m_sourceAdjacencies.equal_range(source); + for (auto mappedIt = range.first; mappedIt != range.second; ++mappedIt) + { + if (m_mapping.contains(mappedIt->second)) + { + adjacent.insert(mappedIt->second); + } + } +} + +void LMRPHeuristic::dijkstraDestroyed(vertex_t source, vertex_t neighbor) +{ + resetDijkstra(); + addAllMapped(neighbor); + nodeset_t adjacentMapped{}; + addAdjacentVertices(source, adjacentMapped); + for (auto adj : adjacentMapped) + { m_edges.unsafe_erase(orderedPair(edge_t{source, adj})); } + + adjacentMapped.unsafe_erase(neighbor); + while(!adjacentMapped.empty()) + { + DijkstraVertex next{}; + while(!m_dijkstraQueue.empty()) + { + next = m_dijkstraQueue.top(); + m_dijkstraQueue.pop(); + if (m_bestPaths[next.m_target].visited()) continue; + bool connected = checkConnectedToSource(adjacentMapped, next.m_target); + if (connected) + { + addEmbeddedPath(next.m_target); + break; + } + addSingleVertexNeighbors(next.m_target, + next.m_overlapCnt, next.m_nonOverlapCnt); + } + if (!adjacentMapped.empty()) + { + resetDijkstra(); + addAllMapped(m_currentSource); + } + } +} + +void LMRPHeuristic::addSingleVertexNeighbors(vertex_t target, + fuint32_t overlaps, fuint32_t length) +{ + const auto& targetGraph = m_state.getTargetAdjGraph(); + auto range = targetGraph.equal_range(target); + for (auto it = range.first; it != range.second; ++it) + { + // std::cout << "Targetgraph (" << it->first << "," << it->second << ")" << std::endl; + if (!m_crater.contains(it->second)) continue; + if (m_bestPaths[it->second].wasVisited()) continue; + auto& neighbor = m_bestPaths[it->second]; + if (neighbor.m_overlapCnt < overlaps) continue; + bool contained = m_superVertices.contains(edge_t{m_currentSource, neighbor.m_target}); + bool count = m_reverse.count(neighbor.m_target); + bool overlap = !contained && count > 0; + bool lowered = neighbor.lowerTo(target, + overlaps + (overlap ? 1 : 0), + length + (contained ? 0 : 1)); + // std::cout << "Adding vertex " << neighbor.m_target << " from " << target << std::endl; + if (lowered) m_dijkstraQueue.push(neighbor); + } +} + +void LMRPHeuristic::runDijkstraToTarget(nodeset_t& targets, vertex_t root) +{ + resetDijkstra(); + // std::cout << "Running Dijkstra from root " << root << " to targets: "<< std::endl; + printNodeset(targets); + vertex_t connectedTo = checkConnectedTo(targets, root); + if (!isDefined(connectedTo)) + { + vertex_t best = FUINT32_UNDEF; + addSingleVertexNeighbors(root, 0, 0); + DijkstraVertex next{}; + while(!m_dijkstraQueue.empty()) + { + next = m_dijkstraQueue.top(); + m_dijkstraQueue.pop(); + if (m_bestPaths[next.m_target].visited()) continue; + connectedTo = checkConnectedTo(targets, next.m_target); + if (isDefined(connectedTo)) + { + best = next.m_target; + break; + } + addSingleVertexNeighbors(next.m_target, + next.m_overlapCnt, next.m_nonOverlapCnt); + } + if (isDefined(best)) addEmbeddedPath(best); + } + if (isDefined(connectedTo)) + { + std::cout << "Removing vertex " << connectedTo << std::endl; + targets.unsafe_erase(connectedTo); + } + else throw std::runtime_error("No connection found!"); +} + +void LMRPHeuristic::addEmbeddedPath(vertex_t leaf) +{ + // std::cout << "Adding the Embedding path" << std::endl; + auto* vertex = &m_bestPaths[leaf]; + while(vertex != nullptr) + { + std::cout << vertex->m_target << " "; + mapVertex(m_currentSource, vertex->m_target); + if (isDefined(vertex->m_parent) && m_bestPaths.contains(vertex->m_parent)) + { + vertex = &m_bestPaths[vertex->m_parent]; + } + else vertex = nullptr; + } + std::cout << std::endl; +} + +vertex_t LMRPHeuristic::checkConnectedTo(const nodeset_t& wantedTargets, + vertex_t target) +{ + const auto& targetGraph = m_state.getTargetAdjGraph(); + auto adjRange = targetGraph.equal_range(target); + for (auto adjIt = adjRange.first; adjIt != adjRange.second; ++adjIt) + { + if (wantedTargets.contains(adjIt->second)) return adjIt->second; + } + + return FUINT32_UNDEF; +} + + +void LMRPHeuristic::addAllMapped(vertex_t source) +{ + const auto& targetGraph = m_state.getTargetAdjGraph(); + nodeset_t closure{}; + auto range = m_mapping.equal_range(source); + for (auto it = range.first; it != range.second; ++it) + { + auto adjRange = targetGraph.equal_range(it->second); + for (auto adjIt = adjRange.first; adjIt != adjRange.second; ++adjIt) + { + if (m_crater.contains(adjIt->second)) closure.insert(adjIt->second); + } + } + const auto& originalMapping = m_state.getMapping(); + auto originalMapped = originalMapping.equal_range(source); + for (auto it = originalMapped.first; it != originalMapped.second; ++it) + { + if (m_border.contains(it->second)) closure.insert(it->second); + } + for (auto it = range.first; it != range.second; ++it) + { + closure.unsafe_erase(it->second); + } + + for (vertex_t adj : closure) + { + m_bestPaths[adj] = DijkstraVertex{adj}; + m_dijkstraQueue.push(m_bestPaths[adj]); + } +} + +void LMRPHeuristic::connectAdjacentComponents(nodeset_t& adjacent) +{ + resetDijkstra(); + addAllMapped(m_currentSource); + DijkstraVertex next{}; + while(!m_dijkstraQueue.empty()) + { + next = m_dijkstraQueue.top(); + m_dijkstraQueue.pop(); + if (m_bestPaths[next.m_target].visited()) continue; + bool connected = checkConnectedToSource(adjacent, next.m_target); + if (connected) + { + addEmbeddedPath(next.m_target); + break; + } + addSingleVertexNeighbors(next.m_target, + next.m_overlapCnt, next.m_nonOverlapCnt); + } +} + +bool LMRPHeuristic::checkConnectedToSource(nodeset_t& wantedSources, vertex_t target) +{ + const auto& targetGraph = m_state.getTargetAdjGraph(); + const auto& originalReverse = m_state.getReverseMapping(); + auto adjRange = targetGraph.equal_range(target); + bool removed = false; + for (auto adjIt = adjRange.first; adjIt != adjRange.second; ++adjIt) + { + auto revRange = (m_crater.contains(adjIt->second) ? + m_reverse.equal_range(adjIt->second) : + originalReverse.equal_range(adjIt->second)); + for (auto revIt = revRange.first; revIt != revRange.second; ++revIt) + { + auto extracted = wantedSources.unsafe_extract(revIt->second); + removed |= !extracted.empty(); + } + } + + return removed; +} + +void LMRPHeuristic::mapVertex(vertex_t source, vertex_t target) +{ + edge_t mapped{source, target}; + if (!m_superVertices.contains(mapped)) + { + m_superVertices.insert(mapped); + m_mapping.insert(mapped); + m_reverse.insert(reversePair(mapped)); + } +} diff --git a/src/lmrp/lmrp_heuristic.hpp b/src/lmrp/lmrp_heuristic.hpp new file mode 100644 index 0000000..d05d1d8 --- /dev/null +++ b/src/lmrp/lmrp_heuristic.hpp @@ -0,0 +1,77 @@ +#ifndef __MAJORMINER_LMRP_HEURISTIC_HPP_ +#define __MAJORMINER_LMRP_HEURISTIC_HPP_ + +#include +#include + +namespace majorminer +{ + + class LMRPHeuristic + { + public: + LMRPHeuristic(EmbeddingState& state, vertex_t target); + void optimize(); + const embedding_mapping_t getMapping() const { return m_mapping; } + + private: + void buildBorder(); + void identifyEdges(); + void identifyEdgesFrom(const nodeset_t& from); + void identifyComponents(); + void buildSubgraphs(graph_t& borderMapped, graph_t& subgraph); + void calculatePreviousFitness(); + void identifyDestroyed(); + void solve(); + + void connectComponent(ConnectedList& component, fuint32_t componentIdx); + void embeddDestroyed(); + void embeddSingleDestroyed(vertex_t source); + + void addReachableComponent(vertex_t target, vertex_t source); + void initializeDijkstraData(); + void resetDijkstra(); + void addSingleVertexNeighbors(vertex_t target, fuint32_t overlaps, fuint32_t length); + void runDijkstraToTarget(nodeset_t& targets, vertex_t root); + vertex_t checkConnectedTo(const nodeset_t& wantedTargets, vertex_t target); + void addEmbeddedPath(vertex_t leaf); + void connectAdjacentComponents(nodeset_t& adjacent); + bool checkConnectedToSource(nodeset_t& wantedSources, vertex_t target); + void addAllMapped(vertex_t source); + + void mapVertex(vertex_t source, vertex_t target); + void addBorderToMapping(); + fuint32_pair_t getLeastMappedNeighbor(vertex_t source); + void dijkstraDestroyed(vertex_t source, vertex_t neighbor); + void mapToFreeVertex(); + void mapToSingleAdjacent(vertex_t neighbor); + void addAdjacentVertices(vertex_t source, nodeset_t& adjacent); + + private: + const EmbeddingState& m_state; + bool m_done; + fuint32_t m_numberOverlaps; + fuint32_t m_numberMapped; + + nodeset_t m_crater; + nodeset_t m_border; + nodeset_t m_completelyDestroyed; + graph_t m_edges; + adjacency_list_t m_sourceAdjacencies; + + Vector m_componentsList; + Vector m_componentVertices; + + embedding_mapping_t m_mapping; + embedding_mapping_t m_reverse; + graph_t m_superVertices; + + PriorityQueue m_dijkstraQueue; + UnorderedMap m_bestPaths; + vertex_t m_currentSource; + }; + + +} + +#endif diff --git a/src/lmrp/lmrp_king_subgraph.cpp b/src/lmrp/lmrp_king_subgraph.cpp new file mode 100644 index 0000000..fbd1cdf --- /dev/null +++ b/src/lmrp/lmrp_king_subgraph.cpp @@ -0,0 +1,69 @@ +#include + +using namespace majorminer; + + +bool KingLMRPSubgraph::getSubgraph(vertex_t contained, nodeset_t& subgraph) +{ + fuint32_t x = m_graph.getXCoord(contained); + fuint32_t y = m_graph.getYCoord(contained); + m_updateLock.lock(); + bool success = !checkOccupation(x, y); + if (success) + { + neighborhood(x,y, + [&](const fuint32_pair_t& pair, bool inCrater){ + if (inCrater) m_occupied.insert(pair); + }); + } + m_updateLock.unlock(); + if (success) + { + subgraph.clear(); + fuint32_t width = m_graph.getWidth(); + neighborhood(x,y, + [&](const fuint32_pair_t& pair, bool inCrater){ + if (inCrater) // pair := (x_coord, y_coord) + { + subgraph.insert(pair.first * width + pair.second); + } + }); + } + return success; +} + +bool KingLMRPSubgraph::isBeingDestroyed(vertex_t contained) +{ + fuint32_t x = m_graph.getXCoord(contained); + fuint32_t y = m_graph.getYCoord(contained); + + m_updateLock.lock_shared(); + bool occupied = checkOccupation(x, y); + m_updateLock.unlock_shared(); + + return occupied; +} + +bool KingLMRPSubgraph::checkOccupation(fuint32_t x, fuint32_t y) const +{ + bool occupied = false; + neighborhood(x,y, + [&](const fuint32_pair_t& pair, bool){ + occupied |= m_occupied.contains(pair); + }); + return occupied; +} + +void KingLMRPSubgraph::commit(vertex_t contained) +{ + fuint32_t x = m_graph.getXCoord(contained); + fuint32_t y = m_graph.getYCoord(contained); + m_updateLock.lock(); + neighborhood(x,y, + [&](const fuint32_pair_t& pair, bool inCrater){ + if (inCrater) m_occupied.unsafe_erase(pair); + }); + m_updateLock.unlock(); +} + + diff --git a/src/lmrp/lmrp_king_subgraph.hpp b/src/lmrp/lmrp_king_subgraph.hpp new file mode 100644 index 0000000..94d01e2 --- /dev/null +++ b/src/lmrp/lmrp_king_subgraph.hpp @@ -0,0 +1,54 @@ +#ifndef __MAJORMINER_LMRP_KING_SUGRAPH_HPP_ +#define __MAJORMINER_LMRP_KING_SUGRAPH_HPP_ + +#include +#include +#include + +namespace majorminer +{ + class KingLMRPSubgraph : public LMRPSubgraph + { + public: + KingLMRPSubgraph(KingGraphInfo& g): m_graph(g) {} + ~KingLMRPSubgraph() {} + + bool getSubgraph(vertex_t contained, nodeset_t& subgraph) override; + + bool isBeingDestroyed(vertex_t contained) override; + + void commit(vertex_t contained) override; + + private: + bool checkOccupation(fuint32_t x, fuint32_t y) const; + + template + void neighborhood(fuint32_t x, fuint32_t y, Functor func) const + { + fuint32_t minX = static_cast(std::max(static_cast(x) - 3, 0)); + fuint32_t maxX = std::min(x + 4, m_graph.getWidth()); + fuint32_t minY = static_cast(std::max(static_cast(y) - 3, 0)); + fuint32_t maxY = std::min(y + 4, m_graph.getHeight()); + + for (fuint32_t itX = minX; itX < maxX; ++itX) + { + bool craterX = ((itX + 3) != x) && (itX - 3 != x); + for (fuint32_t itY = minY; itY < maxY; ++itY) + { + bool isInCrater = craterX && ((itY + 3) != y) && (itY - 3 != y); + func(fuint32_pair_t{itX, itY}, isInCrater); + } + } + } + + private: + KingGraphInfo m_graph; + coordinateset_t m_occupied; + + std::shared_mutex m_updateLock; + }; + +} + + +#endif \ No newline at end of file diff --git a/src/lmrp/lmrp_subgraph.hpp b/src/lmrp/lmrp_subgraph.hpp new file mode 100644 index 0000000..3f5dac2 --- /dev/null +++ b/src/lmrp/lmrp_subgraph.hpp @@ -0,0 +1,24 @@ +#ifndef __MAJORMINER_LMRP_SUBGRAPH_HPP_ +#define __MAJORMINER_LMRP_SUBGRAPH_HPP_ + +#include + + +namespace majorminer +{ + class LMRPSubgraph + { + public: + // Get a subgraph that contains the vertex "contained". Subgraph might not + // be connected. If successful, method returns true. + virtual bool getSubgraph(vertex_t contained, nodeset_t& subgraph) = 0; + + virtual bool isBeingDestroyed(vertex_t contained) = 0; + + // If a LMRP instance was solved, free the mapped vertices + virtual void commit(vertex_t contained) = 0; + }; +} + + +#endif \ No newline at end of file diff --git a/src/lmrp/lmrp_types.cpp b/src/lmrp/lmrp_types.cpp new file mode 100644 index 0000000..80f46c3 --- /dev/null +++ b/src/lmrp/lmrp_types.cpp @@ -0,0 +1,48 @@ +#include "lmrp_types.hpp" + +using namespace majorminer; + +ConnectedList::ConnectedList(vertex_t source, fuint32_t idx, + fuint32_t nbMapped) + : m_source(source), m_idx(idx), + m_nbMapped(nbMapped), m_satisfied(false) {} + +DijkstraVertex::DijkstraVertex(vertex_t target) + : m_target(target) { reset(); } + +DijkstraVertex::DijkstraVertex(vertex_t target, vertex_t parent, + fuint32_t overlapCnt, fuint32_t nonOverlapCnt) + : m_target(target), m_parent(parent), + m_overlapCnt(overlapCnt), m_nonOverlapCnt(nonOverlapCnt), + m_visited(false) {} + +void DijkstraVertex::reset() +{ + m_parent = FUINT32_UNDEF; + m_overlapCnt = FUINT32_UNDEF; + m_nonOverlapCnt = FUINT32_UNDEF; + m_visited = false; +} + +bool DijkstraVertex::lowerTo(fuint32_t parent, fuint32_t overlap, + fuint32_t nonOverlap) +{ + if (overlap < m_overlapCnt || (overlap == m_overlapCnt + && nonOverlap < m_nonOverlapCnt)) + { + //std::cout << "Changing parent from " << m_parent << " to " << parent << std::endl; + m_parent = parent; + m_overlapCnt = overlap; + m_nonOverlapCnt = nonOverlap; + return true; + } + return false; +} + +bool DijkstraVertex::visited() +{ + bool original = m_visited; + m_visited = true; + return original; +} + diff --git a/src/lmrp/lmrp_types.hpp b/src/lmrp/lmrp_types.hpp new file mode 100644 index 0000000..fb4122a --- /dev/null +++ b/src/lmrp/lmrp_types.hpp @@ -0,0 +1,61 @@ +#ifndef __MAJORMINER_LMRP_TYPES_HPP_ +#define __MAJORMINER_LMRP_TYPES_HPP_ + +#include + +namespace majorminer +{ + struct ConnectedList + { + ConnectedList(vertex_t source, fuint32_t idx, fuint32_t nbMapped); + + bool wasSatisfied() const { return m_satisfied; } + void satisfied() { m_satisfied = true; } + + friend bool operator<(const ConnectedList& c1, const ConnectedList& c2) + { return c1.m_source < c2.m_source || (c1.m_source == c2.m_source + && c1.m_nbMapped < c2.m_nbMapped); } + + vertex_t m_source; + fuint32_t m_idx; + fuint32_t m_nbMapped; + bool m_satisfied; + }; + + struct DijkstraVertex + { + public: + DijkstraVertex(){} + DijkstraVertex(vertex_t target); + DijkstraVertex(vertex_t target, vertex_t parent, + fuint32_t overlapCnt, fuint32_t nonOverlapCnt); + + void reset(); + + bool visited(); + + bool wasVisited() const { return m_visited; } + + bool lowerTo(fuint32_t parent, fuint32_t overlap, fuint32_t nonOverlap); + + friend bool operator<(const DijkstraVertex& v1, const DijkstraVertex& v2) + { + return v1.m_overlapCnt < v2.m_overlapCnt || + ( v1.m_overlapCnt == v2.m_overlapCnt + && v1.m_nonOverlapCnt < v2.m_nonOverlapCnt); + } + + friend bool operator==(const DijkstraVertex& v1, const DijkstraVertex& v2) + { return v1.m_target == v2.m_target; } + + vertex_t m_target; + vertex_t m_parent; + fuint32_t m_overlapCnt; + fuint32_t m_nonOverlapCnt; + bool m_visited; + }; +} + + + +#endif \ No newline at end of file diff --git a/src/majorminer.cpp b/src/majorminer.cpp index 7d15aee..13ae1c1 100644 --- a/src/majorminer.cpp +++ b/src/majorminer.cpp @@ -1,335 +1,62 @@ #include "majorminer.hpp" -using namespace majorminer; - -EmbeddingSuite::EmbeddingSuite(const graph_t& source, const graph_t& target, EmbeddingVisualizer* visualizer) - : m_sourceGraph(&source), m_targetGraph(&target), m_visualizer(visualizer) { - convertToAdjacencyList(m_source, source); - convertToAdjacencyList(m_target, target); - for (const auto& arc : target) - { - m_targetNodesRemaining.insert(arc.first); - m_targetNodesRemaining.insert(arc.second); - } - for (const auto& arc : *m_sourceGraph) - { - m_nodesRemaining[arc.first] = 0; - m_nodesRemaining[arc.second] = 0; - m_sourceNeededNeighbors[arc.first]++; - m_sourceNeededNeighbors[arc.second]++; - } -} - -embedding_mapping_t EmbeddingSuite::find_embedding() -{ - while(!m_nodesRemaining.empty()) - { - if (!m_nodesToProcess.empty()) - { - PrioNode node{}; - auto found = m_nodesToProcess.try_pop(node); - if (!found) continue; - if (!m_nodesRemaining.contains(node.m_id)) continue; - m_nodesRemaining.unsafe_erase(node.m_id); - if (node.m_nbConnections > 1) - { - DEBUG(OUT_S << "Complex node to embedd: " << node.m_id << " (" << node.m_nbConnections << ")" << std::endl;) - embeddNode(node.m_id); - if (m_visualizer != nullptr) - { - m_visualizer->draw(m_mapping, [&](std::ostream& os) - { os << "Complex adjacent node " << node.m_id << " (" << node.m_nbConnections << ")";} - ); - } - prepareFrontierShifting(node.m_id, node.m_nbConnections); - } - else - { // nbConnections = 1 - DEBUG(OUT_S << "Simple adjacent node to embedd: " << node.m_id << std::endl;) - embeddSimpleNode(node.m_id); - if (m_visualizer != nullptr) - { - m_visualizer->draw(m_mapping, [&](std::ostream& os) - { os << "Simple adjacent node " << node.m_id << " (1).";} - ); - } - } - updateConnections(node.m_id); - tryMutations(); - } - else - { - // just pick an arbitrary node and place it somewhere - auto node = *m_nodesRemaining.begin(); - m_nodesRemaining.unsafe_erase(m_nodesRemaining.begin()); - DEBUG(OUT_S << "Trivial node to embedd: " << node.first << std::endl;) - embeddTrivialNode(node.first); - if (m_visualizer != nullptr) - { - m_visualizer->draw(m_mapping, [&](std::ostream& os) - { os << "Trivial node " << node.first;} - ); - } - tryMutations(); - } - } - return m_mapping; -} - - -void EmbeddingSuite::embeddNode(fuint32_t node) -{ - embeddNodeNetworkSimplex(node); -} +#include +#include +#include +#include +#include +#include +#include +#include -void EmbeddingSuite::embeddNodeNetworkSimplex(fuint32_t node) -{ - if (m_nsWrapper.get() == nullptr) m_nsWrapper = std::make_unique(this); - - m_nsWrapper->embeddNode(node); -} - - -void EmbeddingSuite::mapNode(fuint32_t node, fuint32_t targetNode) -{ - DEBUG(std::cout << node << " -> " << targetNode << std::endl;) - m_nodesOccupied.insert(targetNode); - m_mapping.insert(std::make_pair(node, targetNode)); - m_reverseMapping.insert(std::make_pair(targetNode, node)); - m_targetNodesRemaining.unsafe_extract(targetNode); - updateNeededNeighbors(node); -} - -void EmbeddingSuite::mapNode(fuint32_t node, const nodeset_t& targetNodes) -{ - DEBUG(OUT_S << node << " -> {";) - for(auto targetNode : targetNodes) - { - DEBUG(OUT_S << " " << targetNode;) - m_nodesOccupied.insert(targetNode); - m_mapping.insert(std::make_pair(node, targetNode)); - m_reverseMapping.insert(std::make_pair(targetNode, node)); - m_targetNodesRemaining.unsafe_extract(targetNode); - } - updateNeededNeighbors(node); - DEBUG(OUT_S << " }" << std::endl;) -} - -void EmbeddingSuite::updateNeededNeighbors(fuint32_t node) -{ - auto range = m_source.equal_range(node); - fuint32_t nbNodes = 0; - for (auto it = range.first; it != range.second; ++it) - { - if (!m_nodesRemaining.contains(it->second)) - { - nbNodes++; - m_sourceNeededNeighbors[it->second]--; - } - } - m_sourceNeededNeighbors[node] -= nbNodes; -} +using namespace majorminer; -void EmbeddingSuite::updateConnections(fuint32_t node) -{ - auto adjacentRange = m_source.equal_range(node); - for (auto adjacentIt = adjacentRange.first; adjacentIt != adjacentRange.second; ++adjacentIt) - { - auto findIt = m_nodesRemaining.find(adjacentIt->second); - if (findIt != m_nodesRemaining.end()) - { - findIt->second += 1; // one of its neighbors is now embedded - m_nodesToProcess.push(PrioNode{findIt->first, findIt->second}); - } - } - identifyAffected(node); -} +EmbeddingSuite::EmbeddingSuite(const graph_t& source, const graph_t& target, EmbeddingVisualizer* visualizer) + : m_state(source, target, visualizer), m_visualizer(visualizer), + m_embeddingManager(*this, m_state), m_mutationManager(m_state, m_embeddingManager), + m_placer(m_state, m_embeddingManager), m_finished(false) +{ } -void EmbeddingSuite::embeddSimpleNode(fuint32_t node) +void EmbeddingSuite::setSubgraphGen(LMRPSubgraph* generator) { - // find a node that is adjacent to the node "adjacentNode" - auto adjacentIt = m_source.equal_range(node); - fuint32_t adjacentNode = -1; - for (auto n = adjacentIt.first; n != adjacentIt.second; ++n) - { - if (!m_nodesRemaining.contains(n->second)) - { - adjacentNode = n->second; - break; - } - } - if (adjacentNode == (fuint32_t)-1) throw std::runtime_error("Could not find the adjacent node."); - - auto embeddedPathIt = m_mapping.equal_range(adjacentNode); - fuint32_t bestNodeFound = adjacentNode; - - for (auto targetNode = embeddedPathIt.first; targetNode != embeddedPathIt.second && bestNodeFound == adjacentNode; ++targetNode) - { - // find nodes that are adjacent to targetNode (in the targetGraph) - auto targetGraphAdjacentIt = m_target.equal_range(targetNode->second); - for (auto targetAdjacent = targetGraphAdjacentIt.first; targetAdjacent != targetGraphAdjacentIt.second; ++targetAdjacent) - { - if (!m_nodesOccupied.contains(targetAdjacent->second)) - { - bestNodeFound = targetAdjacent->second; - break; - } - } - } - // map "node" to "bestNodeFound" - mapNode(node, bestNodeFound); + m_state.setLMRPSubgraphGenerator(generator); } -void EmbeddingSuite::embeddTrivialNode(fuint32_t node) +embedding_mapping_t EmbeddingSuite::find_embedding() { - if (!m_targetNodesRemaining.empty()) + if (m_finished) return m_state.getMapping(); + const auto& nodesRemaining = m_state.getRemainingNodes(); + while(!nodesRemaining.empty()) { - auto targetNode = *m_targetNodesRemaining.begin(); - m_targetNodesRemaining.unsafe_erase(m_targetNodesRemaining.begin()); - mapNode(node, targetNode); - updateConnections(node); - } - else - { - throw std::runtime_error("Oooops..."); + m_placer(); + m_mutationManager(); } + m_mutationManager(true); + m_placer.replaceOverlapping(); + if (m_visualizer != nullptr) finishVisualization(); + m_finished = true; + return m_state.getMapping(); } bool EmbeddingSuite::isValid() const { - EmbeddingValidator validator{m_mapping, *m_sourceGraph, m_target}; + EmbeddingValidator validator{m_state}; return validator.isValid(); } bool EmbeddingSuite::connectsNodes() const { - EmbeddingValidator validator{m_mapping, *m_sourceGraph, m_target}; + EmbeddingValidator validator{m_state}; return validator.nodesConnected(); } -void EmbeddingSuite::identifyAffected(fuint32_t node) +void EmbeddingSuite::finishVisualization() { - m_sourceNodesAffected.clear(); - - // "node" (from source graph) is now mapped to at least one - // target node. Iterate over those, to iterate over their neighbors - // that might be mapped to other source nodes - const auto& reverseMapping = m_reverseMapping; - auto& sourceNodesAffected = m_sourceNodesAffected; - auto& sourceFreeNeighbors = m_sourceFreeNeighbors; - const auto& targetNodesRemaining = m_targetNodesRemaining; - auto& target = m_target; - m_sourceFreeNeighbors[node] = 0; - sourceNodesAffected.insert(node); - auto mappedRange = m_mapping.equal_range(node); - nodeset_t freeAdjNodes {}; - tbb::parallel_for_each(mappedRange.first, mappedRange.second, - [&, this] (const fuint32_pair_t& p){ - auto adjacentRange = target.equal_range(p.second); - nodeset_t nodes{}; // TODO: awful! - for (auto targetAdjacent = adjacentRange.first; targetAdjacent != adjacentRange.second; ++targetAdjacent) - { // if that node is free, note that, else decrement from all mapped - if (targetNodesRemaining.contains(targetAdjacent->second)) freeAdjNodes.insert(targetAdjacent->second); - else - { - auto revMapRange = reverseMapping.equal_range(targetAdjacent->second); - for (auto revIt = revMapRange.first; revIt != revMapRange.second; ++revIt) - { - if (!nodes.contains(revIt->second)) - { - sourceNodesAffected.insert(revIt->second); - sourceFreeNeighbors[revIt->second]--; - nodes.insert(revIt->second); - } - } - } - } - }); - m_sourceFreeNeighbors[node] = freeAdjNodes.size(); -} - -int EmbeddingSuite::numberFreeNeighborsNeeded(fuint32_t sourceNode) -{ - // std::cout << "Source node " << sourceNode << " needs " << m_sourceNeededNeighbors[sourceNode].load() << " neighbors and has " << m_sourceFreeNeighbors[sourceNode].load() << std::endl; - return 2 * m_sourceNeededNeighbors[sourceNode].load() - - std::max(m_sourceFreeNeighbors[sourceNode].load(), 0); -} - -void EmbeddingSuite::prepareFrontierShifting(fuint32_t victimNode, fuint32_t nbConnectedTo) -{ - m_frontierData.clear(); - - auto mapped = m_mapping.equal_range(victimNode); - auto nbMapped = m_mapping.count(victimNode); - if (nbMapped < 4) return; // Bascially useless (or not possible) - - nodeset_t connected{}; - auto adjRange = m_source.equal_range(victimNode); - for (auto adj = adjRange.first; adj != adjRange.second; ++adj) - { if (!m_nodesRemaining.contains(adj->second)) connected.insert(adj->second); } - - for (auto mapIt = mapped.first; mapIt != mapped.second; ++mapIt) - { - auto innerIt = mapIt; - ++innerIt; - for (; innerIt != mapped.second; ++innerIt) - { - edge_t uv{mapIt->second, innerIt->second}; - edge_t vu{innerIt->second, mapIt->second}; - if (m_targetGraph->contains(uv) || - m_targetGraph->contains(vu)) - { - m_frontierData.m_victimSubgraph.insert(uv); - m_frontierData.m_victimSubgraph.insert(vu); - } - } - auto adj = m_target.equal_range(mapIt->second); - for (auto adjNode = adj.first; adjNode != adj.second; ++adjNode) - { - auto revRange = m_reverseMapping.equal_range(adjNode->second); - for (auto revIt = revRange.first; revIt != revRange.second; ++revIt) - { - if (connected.contains(revIt->second)) - { - m_frontierData.addConnection(revIt->second, mapIt->second); - } - } - } - } - m_frontierData.setNbNodes(nbMapped); - m_frontierData.setVictimSource(victimNode); - m_frontierData.findCutVertices(); -} - -void EmbeddingSuite::tryMutations() -{ - auto& queue = m_taskQueue; - if (m_frontierData.m_victimSubgraph.size() > 0) - { - const auto& nodesRemaining = m_nodesRemaining; - auto victimAdjRange = m_source.equal_range(m_frontierData.m_victimSourceNode); - tbb::parallel_for_each(victimAdjRange.first, victimAdjRange.second, - [&](const edge_t& edge){ - if (!nodesRemaining.contains(edge.second)) - { - queue.push(std::make_unique(this, edge.second, edge.first)); - } - }); - m_sourceNodesAffected.unsafe_erase(m_frontierData.m_victimSourceNode); - } - tbb::parallel_for_each(m_sourceNodesAffected.begin(), m_sourceNodesAffected.end(), - [&, this](fuint32_t node){ - queue.push(std::make_unique(this, node)); - }); - - while(!m_taskQueue.empty()) - { - std::unique_ptr task; - bool worked = m_taskQueue.try_pop(task); - if (!worked) break; - task->execute(); - } - m_frontierData.clear(); + fuint32_pair_t stats = calculateOverlappingStats(m_state); + std::stringstream ss; + ss << "Final iteration. Distinct overlaps: " << stats.first + << "; Total overlaps: " << stats.second << std::endl; + m_visualizer->draw(m_state.getMapping(), ss.str().c_str()); } diff --git a/src/majorminer.hpp b/src/majorminer.hpp index 04f7d26..6975f9c 100644 --- a/src/majorminer.hpp +++ b/src/majorminer.hpp @@ -1,87 +1,36 @@ #ifndef __MAJORMINER_MAJOR_MINER_HPP_ #define __MAJORMINER_MAJOR_MINER_HPP_ -#include - -#include "config.hpp" -#include "common/graph_gen.hpp" -#include "common/utils.hpp" -#include "common/embedding_validator.hpp" -#include "common/embedding_visualizer.hpp" -#include "common/cut_vertex.hpp" - -#include "initial/network_simplex.hpp" - -#include "evolutionary/mutation_extend.hpp" -#include "evolutionary/frontier_shifting_data.hpp" -#include "evolutionary/mutation_frontier_shifting.hpp" +#include +#include +#include +#include namespace majorminer { - class NetworkSimplexWrapper; - class GenericMutation; - class MutationExtend; - class MuationFrontierShifting; - struct FrontierShiftingData; - class EmbeddingSuite { - friend NetworkSimplexWrapper; - friend MutationExtend; - friend MuationFrontierShifting; public: EmbeddingSuite(const graph_t& source, const graph_t& target, EmbeddingVisualizer* visualizer = nullptr); embedding_mapping_t find_embedding(); bool isValid() const; bool connectsNodes() const; + void setSubgraphGen(LMRPSubgraph* generator); private: - void embeddNode(fuint32_t node); - void embeddNodeNetworkSimplex(fuint32_t node); - - void mapNode(fuint32_t node, fuint32_t targetNode); - void mapNode(fuint32_t node, const nodeset_t& targetNodes); - void updateConnections(fuint32_t node); - - void prepareFrontierShifting(fuint32_t victimNode, fuint32_t nbConnectedTo); - - void embeddTrivialNode(fuint32_t node); - void embeddSimpleNode(fuint32_t node); - void identifyAffected(fuint32_t node); - - void updateNeededNeighbors(fuint32_t node); - - // query the delta between the number of free nodes - // and the needed amount of by the sourceNode - int numberFreeNeighborsNeeded(fuint32_t sourceNode); - double checkExtendCandidate(fuint32_t extendNode, fuint32_t sourceNode, int delta); - void tryMutations(); + void finishVisualization(); private: - const graph_t* m_sourceGraph; - const graph_t* m_targetGraph; - adjacency_list_t m_source; - adjacency_list_t m_target; - - embedding_mapping_t m_mapping; - embedding_mapping_t m_reverseMapping; - nodeset_t m_nodesOccupied; - nodeset_t m_targetNodesRemaining; - UnorderedMap m_nodesRemaining; - PrioNodeQueue m_nodesToProcess; + EmbeddingState m_state; + EmbeddingVisualizer* m_visualizer; + EmbeddingManager m_embeddingManager; + MutationManager m_mutationManager; + SuperVertexPlacer m_placer; - // TODO: change to priority queue depending on fitness function Queue> m_taskQueue; - UnorderedMap> m_sourceNeededNeighbors; - UnorderedMap> m_sourceFreeNeighbors; - nodeset_t m_sourceNodesAffected; - - FrontierShiftingData m_frontierData; - - std::unique_ptr m_nsWrapper; - EmbeddingVisualizer* m_visualizer; + bool m_finished; }; } diff --git a/src/majorminer_types.hpp b/src/majorminer_types.hpp index e74d997..2f18bde 100644 --- a/src/majorminer_types.hpp +++ b/src/majorminer_types.hpp @@ -1,25 +1,37 @@ #ifndef __MAJORMINER_TYPES_HPP_ #define __MAJORMINER_TYPES_HPP_ -#include +#include "common/config.hpp" + #include #include #include #include #include +#include #include +#include + #include #include +#include #include #include - -#include "config.hpp" +#include +#include +#include +#include +#include namespace majorminer { typedef uint_fast32_t fuint32_t; + typedef std::pair fuint32_pair_t; + typedef fuint32_t vertex_t; + + const static fuint32_t FUINT32_UNDEF = (fuint32_t)-1; template struct PairHashFunc @@ -35,18 +47,31 @@ namespace majorminer struct PrioNode { PrioNode() : m_id(-1), m_nbConnections(0) {} - PrioNode(fuint32_t id, fuint32_t nbConnections = 0) + PrioNode(vertex_t id, fuint32_t nbConnections = 0) : m_id(id), m_nbConnections(nbConnections) {} friend bool operator<(const PrioNode& n1, const PrioNode& n2) { return n1.m_nbConnections < n2.m_nbConnections; } - fuint32_t m_id; + vertex_t m_id; fuint32_t m_nbConnections; }; + struct NodePair + { + NodePair() : source(FUINT32_UNDEF), target(FUINT32_UNDEF) {} + NodePair(vertex_t s, vertex_t t) : source(s), target(t) {} + NodePair(const fuint32_pair_t& p): source(p.first), target(p.second) {} + + friend bool operator==(const NodePair& p1, const NodePair& p2) + { return p1.source == p2.source && p1.target == p2.target; } + + vertex_t source; + vertex_t target; + }; + template> - using Vector = tbb::concurrent_vector; + using Vector = std::vector; template, typename Allocator = std::allocator> using UnorderedSet = tbb::concurrent_unordered_set, Allocator>; @@ -58,22 +83,57 @@ namespace majorminer using UnorderedMultiMap = tbb::concurrent_unordered_multimap, Allocator>; template> - using PriorityQueue = tbb::concurrent_priority_queue; + using PriorityQueue = std::priority_queue, Comparator>; + + template> + using ConcurrentPriorityQueue = tbb::concurrent_priority_queue; + template using Queue = tbb::concurrent_queue; + template + using BoundedQueue = tbb::concurrent_bounded_queue; + template using Stack = std::stack>; - typedef std::pair fuint32_pair_t; + template + using Cache = tbb::concurrent_lru_cache; + typedef fuint32_pair_t edge_t; - typedef UnorderedSet> graph_t; - typedef UnorderedMultiMap adjacency_list_t; + typedef UnorderedMap VertexNumberMap; + typedef UnorderedSet> graph_t; + typedef UnorderedMultiMap adjacency_list_t; typedef adjacency_list_t embedding_mapping_t; - typedef UnorderedSet nodeset_t; + typedef UnorderedSet nodeset_t; + typedef UnorderedSet> nodepairset_t; + typedef nodepairset_t coordinateset_t; typedef PriorityQueue> PrioNodeQueue; + typedef std::pair adjacency_list_range_iterator_t; + + typedef std::pair> ShiftingCandidates; + typedef Cache CandidateCache; + + struct ChimeraGraphInfo; + class EmbeddingVisualizer; + class EmbeddingSuite; + class EmbeddingBase; + class EmbeddingState; + class EmbeddingManager; + class SuperVertexPlacer; + class SuperVertexReducer; + class EvolutionaryCSCReducer; + class GenericMutation; + class MutationExtend; + class MuationFrontierShifting; + class MutationReduceOverlap; + class MutationManager; + class NetworkSimplexWrapper; + class RandomGen; + class ThreadManager; + class LMRPSubgraph; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index be52db9..fc6623d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -7,6 +7,9 @@ target_sources(majorminer_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test_qubo_problems.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_graph_gen.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_main.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_perf.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_qubo_modelling.cpp ${CMAKE_CURRENT_SOURCE_DIR}/test_cut_vertex.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_reducer.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/test_lmrp.cpp ) \ No newline at end of file diff --git a/test/test_cut_vertex.cpp b/test/test_cut_vertex.cpp index c3486cb..ddf23fb 100644 --- a/test/test_cut_vertex.cpp +++ b/test/test_cut_vertex.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "utils/test_common.hpp" diff --git a/test/test_graph_gen.cpp b/test/test_graph_gen.cpp index 503625f..e3da228 100644 --- a/test/test_graph_gen.cpp +++ b/test/test_graph_gen.cpp @@ -1,5 +1,7 @@ #include "utils/test_common.hpp" +#include + using namespace majorminer; @@ -92,4 +94,5 @@ TEST(CycleGraphGen, Cycle_1) auto graph = majorminer::generate_cyclegraph(1); EXPECT_EQ(graph.size(), 0); containsEdges(graph, {}); -} \ No newline at end of file +} + diff --git a/test/test_lmrp.cpp b/test/test_lmrp.cpp new file mode 100644 index 0000000..8675cb7 --- /dev/null +++ b/test/test_lmrp.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/test_common.hpp" +#include "utils/state_gen.hpp" + +using namespace majorminer; + + +TEST(LMRPTest, SimpleChimera) +{ + auto chimera = majorminer::generate_chimera(3, 3); + ChimeraGraphInfo info{3,3}; + ChimeraLMRPSubgraph subgraph{info}; + graph_t trivial{ { 0, 1 }, {0, 2} }; + StateGen gen{trivial, chimera}; + gen.addMapping(0, { 3, 7, 12, 13, 14, 15, 8, 32, 56, 62, 70}); + gen.addMapping(1, {37, 45}); + gen.addMapping(2, {36}); + auto state = gen.get(); + state->setLMRPSubgraphGenerator(&subgraph); + LMRPHeuristic lmrp{*state, 32}; + lmrp.optimize(); + auto repaired = lmrp.getMapping(); + for (auto mapped : repaired) + { + std::cout << mapped.first << " --> " << mapped.second << std::endl; + } +} + + +TEST(LMRPTest, SimpleKings) +{ + auto chimera = majorminer::generate_king(7, 7); + KingGraphInfo info{7,7}; + KingLMRPSubgraph subgraph{info}; + graph_t trivial{{ 0, 1 }, {0, 2}, {1, 2}}; + StateGen gen{trivial, chimera}; + gen.addMapping(0, { 21,22,23,31,25,26,27}); + gen.addMapping(1, { 3, 10, 17, 24, 30, 38, 45}); + gen.addMapping(2, {0, 8, 16}); + auto state = gen.get(); + state->setLMRPSubgraphGenerator(&subgraph); + LMRPHeuristic lmrp{*state, 24}; + lmrp.optimize(); + auto repaired = lmrp.getMapping(); + for (auto mapped : repaired) + { + std::cout << mapped.first << " --> " << mapped.second << std::endl; + } +} + +TEST(LMRPTest, TrivialKings_SingleConnection) +{ + auto chimera = majorminer::generate_king(7, 7); + KingGraphInfo info{7,7}; + KingLMRPSubgraph subgraph{info}; + graph_t trivial{ }; + StateGen gen{trivial, chimera}; + gen.addMapping(0, {21,22,23,31,25,26,27}); + auto state = gen.get(); + state->setLMRPSubgraphGenerator(&subgraph); + LMRPHeuristic lmrp{*state, 24}; + lmrp.optimize(); + auto repaired = lmrp.getMapping(); +} \ No newline at end of file diff --git a/test/test_main.cpp b/test/test_main.cpp index 6098b16..5b4575f 100644 --- a/test/test_main.cpp +++ b/test/test_main.cpp @@ -2,19 +2,57 @@ #include #include #include +#include +#include #include "utils/test_common.hpp" #include "utils/qubo_problems.hpp" using namespace majorminer; +namespace +{ + coordinate_map_t getPetersenCoordinates() + { + coordinate_map_t coords{ + std::make_pair(0, Coordinate_t( 7.0, 0.0 )), + std::make_pair(1, Coordinate_t( 13.657, 4.837 )), + std::make_pair(2, Coordinate_t( 11.114, 12.663 )), + std::make_pair(3, Coordinate_t( 2.8859999999999992, 12.663 )), + std::make_pair(4, Coordinate_t( 0.34299999999999997, 4.837 )), + std::make_pair(5, Coordinate_t( 7.0, 3.0 )), + std::make_pair(6, Coordinate_t( 10.804, 5.763999999999999 )), + std::make_pair(7, Coordinate_t( 9.350999999999999, 10.236 )), + std::make_pair(8, Coordinate_t( 4.648999999999999, 10.236 )), + std::make_pair(9, Coordinate_t( 3.1959999999999997, 5.763999999999999 )) + }; + return coords; + } + + void clique_test(fuint32_t n, fuint32_t x, fuint32_t y, std::string filename, + bool fullValidation = false, bool visualize = true, bool printStats = false) + { + graph_t clique = generate_completegraph(n); + graph_t chimera = generate_chimera(x, y); + std::cout << filename << std::endl; + std::unique_ptr visualizer; + if (visualize) visualizer = std::make_unique(clique, chimera, filename, x, y); + EmbeddingSuite suite{clique, chimera, visualize ? visualizer.get() : nullptr}; + auto embedding = suite.find_embedding(); + + if (printStats) printEmbeddingOverlapStats(embedding); + + if (fullValidation) ASSERT_TRUE(suite.isValid()); + else ASSERT_TRUE(suite.connectsNodes()); + } +} TEST(EmbeddingTest, Basic_Cycle_4) { graph_t cycle = generate_cyclegraph(4); graph_t chimera = generate_chimera(1, 1); auto visualizer = std::make_unique(cycle, chimera, "imgs/Basic_Cycle_4/chimera_cycle_4", 1, 1); - EmbeddingSuite suite{cycle, chimera}; + EmbeddingSuite suite{cycle, chimera, visualizer.get()}; auto embedding = suite.find_embedding(); ASSERT_TRUE(suite.isValid()); } @@ -25,9 +63,9 @@ TEST(EmbeddingTest, Cycle_5_Extra_Edges) graph_t chimera = generate_chimera(1, 1); addEdges(cycle, { {0,2}, {2, 4}, {1,3}}); auto visualizer = std::make_unique(cycle, chimera, "imgs/Cycle_5_Extra_Edges/chimera_cycle_5_ExtraEdges", 1, 1); - EmbeddingSuite suite{cycle, chimera}; + EmbeddingSuite suite{cycle, chimera, visualizer.get()}; auto embedding = suite.find_embedding(); - ASSERT_TRUE(suite.isValid()); + ASSERT_TRUE(suite.connectsNodes()); } TEST(EmbeddingTest, Cycle_5_Extra_Edges_On_2_2_Chimera) @@ -43,12 +81,63 @@ TEST(EmbeddingTest, Cycle_5_Extra_Edges_On_2_2_Chimera) TEST(EmbeddingTest, Complete_Graph_8_On_3_3_Chimera) { - graph_t clique = generate_completegraph(8); - graph_t chimera = generate_chimera(3, 3); - auto visualizer = std::make_unique(clique, chimera, "imgs/Complete_Graph_8_On_3_3_Chimera/chimera_clique_8", 3, 3); - EmbeddingSuite suite{clique, chimera, visualizer.get()}; - auto embedding = suite.find_embedding(); - ASSERT_TRUE(suite.connectsNodes()); + clique_test(8, 3, 3, "imgs/Complete_Graph_8_On_3_3_Chimera/chimera_clique_8", false); +} + + +TEST(EmbeddingTest, Complete_Graph_12_On_5_5_Chimera) +{ + clique_test(12, 5, 5, "imgs/Complete_Graph_12_On_5_5_Chimera/chimera_clique_12", false); +} + + +TEST(EmbeddingTest, Complete_Graph_15_On_7_7_Chimera) +{ + clique_test(15, 7, 7, "imgs/Complete_Graph_15_On_7_7_Chimera/chimera_clique_15", false); +} + + +TEST(EmbeddingTest, Complete_Graph_18_On_9_9_Chimera) +{ + clique_test(18, 9, 9, "imgs/Complete_Graph_18_On_9_9_Chimera/chimera_clique_18", false); +} + +TEST(EmbeddingTest, Complete_Graph_21_On_11_11_Chimera) +{ + clique_test(21, 11, 11, "imgs/Complete_Graph_21_On_11_11_Chimera/chimera_clique_21", false); +} + +TEST(EmbeddingTest, Complete_Graph_25_On_16_16_Chimera) +{ + clique_test(25, 16, 16, "imgs/Complete_Graph_25_On_16_16_Chimera/chimera_clique_25", false); +} + + +TEST(EmbeddingTest, Complete_Graph_28_On_16_16_Chimera) +{ + clique_test(28, 16, 16, "imgs/Complete_Graph_28_On_16_16_Chimera/chimera_clique_28", false); +} + + +TEST(EmbeddingTest, Complete_Graph_31_On_16_16_Chimera) +{ + clique_test(31, 16, 16, "imgs/Complete_Graph_31_On_16_16_Chimera/chimera_clique_31", false, false); +} + +TEST(EmbeddingTest, Complete_Graph_33_On_16_16_Chimera) +{ + clique_test(33, 16, 16, "imgs/Complete_Graph_33_On_16_16_Chimera/chimera_clique_33", false, false, false); +} + +TEST(EmbeddingTest, Complete_Graph_34_On_16_16_Chimera) +{ + clique_test(34, 16, 16, "imgs/Complete_Graph_34_On_16_16_Chimera/chimera_clique_34", false, false); +} + + +TEST(EmbeddingTest, Complete_Graph_25_On_8_8_Chimera) +{ + clique_test(25, 8, 8, "imgs/Complete_Graph_25_On_8_8_Chimera/chimera_clique_25", false, false); } TEST(EmbeddingTest, Basic_Cycle_8_Visualization) @@ -58,6 +147,7 @@ TEST(EmbeddingTest, Basic_Cycle_8_Visualization) auto visualizer = std::make_unique(cycle, chimera, "imgs/Basic_Cycle_8_Visualization/chimera_cycle_8", 2, 2); EmbeddingSuite suite{cycle, chimera, visualizer.get()}; auto embedding = suite.find_embedding(); + ASSERT_TRUE(suite.isValid()); } TEST(EmbeddingTest, Petersen_Chimera) @@ -67,6 +157,7 @@ TEST(EmbeddingTest, Petersen_Chimera) auto visualizer = std::make_unique(petersen, chimera, "imgs/Petersen_Chimera/chimera_petersen", 2, 2); EmbeddingSuite suite{petersen, chimera, visualizer.get()}; auto embedding = suite.find_embedding(); + ASSERT_TRUE(suite.connectsNodes()); } @@ -77,6 +168,7 @@ TEST(EmbeddingTest, Petersen_KingsGraph) auto visualizer = std::make_unique(petersen, king, "imgs/Petersen_KingsGraph/king_petersen", 10, 10); EmbeddingSuite suite{petersen, king, visualizer.get()}; auto embedding = suite.find_embedding(); + ASSERT_TRUE(suite.connectsNodes()); } TEST(EmbeddingTest, DISABLED_TSP_7) @@ -92,3 +184,38 @@ TEST(EmbeddingTest, DISABLED_TSP_7) << analyzer.getNbUsedNodes() << " nodes were needed." << std::endl; } + +TEST(EmbeddingTest, K33_On_Petersen_Kuratowski) +{ + graph_t petersen = majorminer::generate_petersen(); + graph_t k33{}; + addEdges(k33, { + {0,3}, {0,4}, {0,5}, + {1,3}, {1,4}, {1,5}, + {2,3}, {2,4}, {2,5} + }); + auto coords = getPetersenCoordinates(); + auto visualizer = std::make_unique(k33, petersen, "imgs/PetersenNotPlanar/petersen_kuratowski", coords, 14, 14); + EmbeddingSuite suite{k33, petersen, visualizer.get()}; + auto embedding = suite.find_embedding(); + ASSERT_TRUE(suite.connectsNodes()); +} + + +TEST(EmbeddingTest, ErdosRenyi_Chimera_7_7) +{ + graph_t erdos = generate_erdosrenyi(35, 0.1); + graph_t chimera = generate_chimera(7, 7); + auto visualizer = std::make_unique(erdos, chimera, "imgs/ErdosRenyi_Chimera_7_7/ErdosRenyi_Chimera_7_7", 7, 7); + EmbeddingSuite suite { erdos, chimera, visualizer.get() }; + suite.find_embedding(); + ASSERT_TRUE(suite.connectsNodes()); +} + +TEST(EmbeddingTest, DISABLED_RunMultipleTimes) +{ + for (int i = 0; i < 100; ++i) + { + clique_test(33, 16, 16, "imgs/Complete_Graph_33_On_16_16_Chimera/chimera_clique_33", false, false, false); + } +} \ No newline at end of file diff --git a/test/test_perf.cpp b/test/test_perf.cpp new file mode 100644 index 0000000..144c9f9 --- /dev/null +++ b/test/test_perf.cpp @@ -0,0 +1,20 @@ +#include +#include +#include +#include + +#include "utils/test_common.hpp" +#include "utils/qubo_problems.hpp" + +using namespace majorminer; + +TEST(PerfTest, CompleteLarge_21) +{ + graph_t clique = generate_completegraph(21); + graph_t chimera = generate_chimera(11, 11); + EmbeddingSuite suite{clique, chimera}; + auto embedding = suite.find_embedding(); + ASSERT_TRUE(suite.connectsNodes()); +} + + diff --git a/test/test_reducer.cpp b/test/test_reducer.cpp new file mode 100644 index 0000000..8a7cb52 --- /dev/null +++ b/test/test_reducer.cpp @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils/state_gen.hpp" + +using namespace majorminer; + +namespace +{ + void getWorstSource(const embedding_mapping_t& mapping, vertex_t& source) + { + embedding_mapping_t reverse{}; + for (const auto& mapped : mapping) reverse.insert(std::make_pair(mapped.second, mapped.first)); + VertexNumberMap stats{}; + for (const auto& rev : reverse) stats[rev.second] = 0; + for (const auto& rev : reverse) + { + if (reverse.count(rev.first) >= 2) stats[rev.second]++; + } + fuint32_t worstNumber = 0; + for (const auto& stat : stats) + { + if (stat.second >= worstNumber) + { + worstNumber = stat.second; + source = stat.first; + } + } + std::cout << "Worst is " << source << std::endl; + } + + void runTest(const graph_t& source, const graph_t& target, EmbeddingVisualizer* visualizer, vertex_t sourceVertex) + { + EmbeddingSuite suite{source, target}; + embedding_mapping_t mapping = suite.find_embedding(); + ASSERT_TRUE(suite.connectsNodes()); + StateGen gen {source, target}; + gen.addMapping(mapping); + auto state = gen.get(); + + if (!isDefined(sourceVertex)) getWorstSource(mapping, sourceVertex); + EvolutionaryCSCReducer reducer{*state, sourceVertex}; + reducer.setVisualizer(visualizer); + reducer.optimize(); + + StateGen adjusted{source, target}; + adjusted.addMapping(mapping); + adjusted.removeSuperVertex(sourceVertex); + adjusted.addMapping(sourceVertex, reducer.getPlacement()); + auto newState = adjusted.get(); + EmbeddingValidator validator{*newState}; + ASSERT_TRUE(validator.nodesConnected()); + } +} + +TEST(ReducerTest, SimpleEvoReducer) +{ + graph_t clique = majorminer::generate_completegraph(18); + graph_t chimera = majorminer::generate_chimera(8,8); + auto visualizer = std::make_unique(clique, chimera, "imgs/SimpleEvoReducer/SimpleEvoReducer", 8,8); + runTest(clique, chimera, visualizer.get(), FUINT32_UNDEF); +} diff --git a/test/utils/CMakeLists.txt b/test/utils/CMakeLists.txt index 38a5092..0fa9cae 100644 --- a/test/utils/CMakeLists.txt +++ b/test/utils/CMakeLists.txt @@ -3,4 +3,5 @@ target_sources(majorminer_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/test_common.cpp ${CMAKE_CURRENT_SOURCE_DIR}/qubo_modelling.cpp ${CMAKE_CURRENT_SOURCE_DIR}/qubo_problems.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/state_gen.cpp ) \ No newline at end of file diff --git a/test/utils/qubo_modelling.cpp b/test/utils/qubo_modelling.cpp index f41d0c1..8d3f0b0 100644 --- a/test/utils/qubo_modelling.cpp +++ b/test/utils/qubo_modelling.cpp @@ -361,7 +361,7 @@ bool QEnumerationVerifier::verify() } else if (returned) { - m_setting[idx] ^= true; // toggle bit + m_setting[idx] = (m_setting[idx] ^ true); // toggle bit if (m_setting[idx] == false) continue; else returned = false; } diff --git a/test/utils/state_gen.cpp b/test/utils/state_gen.cpp new file mode 100644 index 0000000..e828f0b --- /dev/null +++ b/test/utils/state_gen.cpp @@ -0,0 +1,53 @@ +#include "state_gen.hpp" + +using namespace majorminer; + +void StateGen::addMapping(std::initializer_list mapping) +{ + m_mapping.insert(mapping.begin(), mapping.end()); +} + +void StateGen::addMapping(vertex_t source, std::initializer_list targetVertices) +{ + for (auto target : targetVertices) + { + m_mapping.insert(std::make_pair(source, target)); + } +} + +void StateGen::addMapping(const embedding_mapping_t& mapping) +{ + for (const auto& mapped : mapping) + { + m_mapping.insert(mapped); + } +} + +void StateGen::addMapping(vertex_t source, const nodeset_t& mapping) +{ + for (auto target : mapping) m_mapping.insert(std::make_pair(source, target)); +} + +std::unique_ptr StateGen::get() +{ + auto state = std::make_unique(m_source, m_target, nullptr); + auto& remaining = state->getRemainingTargetNodes(); + auto& occupied = state->getNodesOccupied(); + for (const auto& edge : m_mapping) + { + state->mapNode(edge.first, edge.second); + remaining.unsafe_erase(edge.second); + occupied.insert(edge.first); + } + return state; +} + +void StateGen::removeSuperVertex(vertex_t sourceVertex) +{ + graph_t remove{}; + for (const auto& mapped : m_mapping) + { + if (mapped.first == sourceVertex) remove.insert(mapped); + } + for (const auto& mapped : remove) m_mapping.unsafe_erase(mapped); +} diff --git a/test/utils/state_gen.hpp b/test/utils/state_gen.hpp new file mode 100644 index 0000000..25ac9df --- /dev/null +++ b/test/utils/state_gen.hpp @@ -0,0 +1,35 @@ +#ifndef __MAJORMINER_STATE_GEN_HPP_ +#define __MAJORMINER_STATE_GEN_HPP_ + +#include +#include + +namespace majorminer +{ + + class StateGen + { + public: + StateGen(const graph_t& source, const graph_t& target) + : m_source(source), m_target(target) {} + + void addMapping(const embedding_mapping_t& mapping); + void addMapping(std::initializer_list mapping); + void addMapping(vertex_t source, const nodeset_t& mapping); + void addMapping(vertex_t source, std::initializer_list targetVertices); + std::unique_ptr get(); + std::unique_ptr operator()() { return get(); } + + void removeSuperVertex(vertex_t sourceVertex); + + private: + const graph_t& m_source; + const graph_t& m_target; + + graph_t m_mapping; + }; + +} + + +#endif \ No newline at end of file diff --git a/test/utils/test_common.cpp b/test/utils/test_common.cpp index 517f92a..418cce3 100644 --- a/test/utils/test_common.cpp +++ b/test/utils/test_common.cpp @@ -1,5 +1,7 @@ #include "test_common.hpp" +#include + using namespace majorminer; namespace @@ -90,15 +92,3 @@ nodeset_t majorminer::getNodeset(const graph_t& graph) }); return nodes; } - - -void majorminer::printNodeset(const nodeset_t& nodes) -{ - Vector nodeVec{}; - nodeVec.reserve(nodes.size()); - for (auto n : nodes) nodeVec.push_back(n); - tbb::parallel_sort(nodeVec.begin(), nodeVec.end()); - std::cout << "Nodeset: { "; - for (auto n : nodeVec) std::cout << n << " "; - std::cout << "}" << std::endl; -} \ No newline at end of file