├── .here ├── models ├── SAR │ ├── console.txt │ ├── SAR_output.csv │ ├── .RData │ ├── .Rhistory │ └── genom.csv ├── SYM │ ├── console.txt │ ├── SYM_output.csv │ ├── .RData │ ├── soil_fertility.asc │ └── genom.csv ├── WYLD │ ├── .Rhistory │ ├── console.txt │ ├── WYLD_output.csv │ ├── .RData │ └── genom.csv └── HabStruct │ ├── console.txt │ ├── HabStruct_output.csv │ ├── .RData │ └── genom.csv ├── input ├── worst_fitness_values_maximize.txt ├── min_max.txt ├── Helperscripts_for_Input │ ├── .DS_Store │ └── nws │ │ ├── .RData │ │ ├── .DS_Store │ │ └── landusefrompatchmap.R └── transition_matrix.txt ├── .RData ├── README.md ├── .gitattributes ├── CoMOLA_flowchart.png ├── __pycache__ ├── config.cpython-311.pyc ├── config.cpython-33.pyc ├── __init__.cpython-311.pyc ├── filehandler.cpython-311.pyc ├── filehandler.cpython-33.pyc ├── maphandler.cpython-311.pyc ├── requirements.cpython-33.pyc ├── optiAlgorithm.cpython-311.pyc ├── optiAlgorithm.cpython-33.pyc └── requirements.cpython-311.pyc ├── inspyred ├── ec │ ├── variators │ │ ├── __init__.pyc │ │ ├── mutators.pyc │ │ ├── crossovers.pyc │ │ ├── variators.pyc │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-33.pyc │ │ │ ├── mutators.cpython-33.pyc │ │ │ ├── __init__.cpython-311.pyc │ │ │ ├── crossovers.cpython-33.pyc │ │ │ ├── mutators.cpython-311.pyc │ │ │ ├── variators.cpython-311.pyc │ │ │ ├── variators.cpython-33.pyc │ │ │ └── crossovers.cpython-311.pyc │ │ ├── variators.py │ │ ├── __init__.py │ │ └── mutators.py │ ├── __pycache__ │ │ ├── ec.cpython-311.pyc │ │ ├── ec.cpython-33.pyc │ │ ├── emo.cpython-33.pyc │ │ ├── emo.cpython-311.pyc │ │ ├── __init__.cpython-33.pyc │ │ ├── analysis.cpython-33.pyc │ │ ├── __init__.cpython-311.pyc │ │ ├── analysis.cpython-311.pyc │ │ ├── archivers.cpython-311.pyc │ │ ├── archivers.cpython-33.pyc │ │ ├── evaluators.cpython-33.pyc │ │ ├── generators.cpython-33.pyc │ │ ├── migrators.cpython-311.pyc │ │ ├── migrators.cpython-33.pyc │ │ ├── observers.cpython-311.pyc │ │ ├── observers.cpython-33.pyc │ │ ├── replacers.cpython-311.pyc │ │ ├── replacers.cpython-33.pyc │ │ ├── selectors.cpython-311.pyc │ │ ├── selectors.cpython-33.pyc │ │ ├── utilities.cpython-311.pyc │ │ ├── utilities.cpython-33.pyc │ │ ├── evaluators.cpython-311.pyc │ │ ├── generators.cpython-311.pyc │ │ ├── terminators.cpython-311.pyc │ │ └── terminators.cpython-33.pyc │ ├── __init__.py │ ├── generators.py │ ├── migrators.py │ ├── utilities.py │ ├── emo.py │ ├── evaluators.py │ ├── selectors.py │ ├── archivers.py │ ├── terminators.py │ └── analysis.py ├── __pycache__ │ ├── __init__.cpython-33.pyc │ ├── __init__.cpython-311.pyc │ ├── benchmarks.cpython-311.pyc │ └── benchmarks.cpython-33.pyc ├── swarm │ ├── __pycache__ │ │ ├── swarm.cpython-33.pyc │ │ ├── swarm.cpython-311.pyc │ │ ├── __init__.cpython-311.pyc │ │ ├── __init__.cpython-33.pyc │ │ ├── topologies.cpython-33.pyc │ │ └── topologies.cpython-311.pyc │ ├── __init__.py │ ├── topologies.py │ └── swarm.py └── __init__.py ├── output_analysis ├── Example_output.png └── CoMOLA_postprocessing.R ├── environment.yml ├── guides └── Starting CoMOLA on your personal Desktop.pdf ├── dockerfile ├── requirements.py ├── config.ini └── __init__.py /.here: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/SAR/console.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/SYM/console.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/WYLD/.Rhistory: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/WYLD/console.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/HabStruct/console.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/SAR/SAR_output.csv: -------------------------------------------------------------------------------- 1 | 24.2724704986966 2 | -------------------------------------------------------------------------------- /models/SYM/SYM_output.csv: -------------------------------------------------------------------------------- 1 | 54784.6378366201 2 | -------------------------------------------------------------------------------- /models/WYLD/WYLD_output.csv: -------------------------------------------------------------------------------- 1 | 43720.1159712344 2 | -------------------------------------------------------------------------------- /models/HabStruct/HabStruct_output.csv: -------------------------------------------------------------------------------- 1 | 912.116666666667 2 | -------------------------------------------------------------------------------- /input/worst_fitness_values_maximize.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | -------------------------------------------------------------------------------- /.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/.RData -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/README.md -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /models/SAR/.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/models/SAR/.RData -------------------------------------------------------------------------------- /models/SYM/.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/models/SYM/.RData -------------------------------------------------------------------------------- /models/WYLD/.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/models/WYLD/.RData -------------------------------------------------------------------------------- /CoMOLA_flowchart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/CoMOLA_flowchart.png -------------------------------------------------------------------------------- /models/HabStruct/.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/models/HabStruct/.RData -------------------------------------------------------------------------------- /__pycache__/config.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/config.cpython-311.pyc -------------------------------------------------------------------------------- /__pycache__/config.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/config.cpython-33.pyc -------------------------------------------------------------------------------- /input/min_max.txt: -------------------------------------------------------------------------------- 1 | land_use 1 2 3 4 5 6 7 8 2 | min 0 0 0 0 0 0 0 0 3 | max 100 100 100 100 100 100 100 100 4 | 5 | 6 | -------------------------------------------------------------------------------- /inspyred/ec/variators/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__init__.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/mutators.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/mutators.pyc -------------------------------------------------------------------------------- /output_analysis/Example_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/output_analysis/Example_output.png -------------------------------------------------------------------------------- /__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/crossovers.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/crossovers.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/variators.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/variators.pyc -------------------------------------------------------------------------------- /__pycache__/filehandler.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/filehandler.cpython-311.pyc -------------------------------------------------------------------------------- /__pycache__/filehandler.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/filehandler.cpython-33.pyc -------------------------------------------------------------------------------- /__pycache__/maphandler.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/maphandler.cpython-311.pyc -------------------------------------------------------------------------------- /__pycache__/requirements.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/requirements.cpython-33.pyc -------------------------------------------------------------------------------- /input/Helperscripts_for_Input/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/input/Helperscripts_for_Input/.DS_Store -------------------------------------------------------------------------------- /__pycache__/optiAlgorithm.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/optiAlgorithm.cpython-311.pyc -------------------------------------------------------------------------------- /__pycache__/optiAlgorithm.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/optiAlgorithm.cpython-33.pyc -------------------------------------------------------------------------------- /__pycache__/requirements.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/__pycache__/requirements.cpython-311.pyc -------------------------------------------------------------------------------- /input/Helperscripts_for_Input/nws/.RData: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/input/Helperscripts_for_Input/nws/.RData -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/ec.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/ec.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/ec.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/ec.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/emo.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/emo.cpython-33.pyc -------------------------------------------------------------------------------- /input/Helperscripts_for_Input/nws/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/input/Helperscripts_for_Input/nws/.DS_Store -------------------------------------------------------------------------------- /inspyred/__pycache__/__init__.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/__pycache__/__init__.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/emo.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/emo.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/__pycache__/benchmarks.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/__pycache__/benchmarks.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/__pycache__/benchmarks.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/__pycache__/benchmarks.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/__init__.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/__init__.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/analysis.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/analysis.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/swarm/__pycache__/swarm.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/swarm/__pycache__/swarm.cpython-33.pyc -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: Comola 2 | channels: 3 | - defaults 4 | - conda-forge 5 | dependencies: 6 | - python=3.10 7 | - matplotlib 8 | - r-base -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/analysis.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/analysis.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/archivers.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/archivers.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/archivers.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/archivers.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/evaluators.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/evaluators.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/generators.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/generators.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/migrators.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/migrators.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/migrators.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/migrators.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/observers.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/observers.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/observers.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/observers.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/replacers.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/replacers.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/replacers.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/replacers.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/selectors.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/selectors.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/selectors.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/selectors.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/utilities.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/utilities.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/utilities.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/utilities.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/swarm/__pycache__/swarm.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/swarm/__pycache__/swarm.cpython-311.pyc -------------------------------------------------------------------------------- /guides/Starting CoMOLA on your personal Desktop.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/guides/Starting CoMOLA on your personal Desktop.pdf -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/evaluators.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/evaluators.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/generators.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/generators.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/terminators.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/terminators.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/__pycache__/terminators.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/__pycache__/terminators.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/swarm/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/swarm/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/swarm/__pycache__/__init__.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/swarm/__pycache__/__init__.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/swarm/__pycache__/topologies.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/swarm/__pycache__/topologies.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/swarm/__pycache__/topologies.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/swarm/__pycache__/topologies.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/__init__.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/__init__.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/mutators.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/mutators.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/crossovers.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/crossovers.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/mutators.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/mutators.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/variators.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/variators.cpython-311.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/variators.cpython-33.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/variators.cpython-33.pyc -------------------------------------------------------------------------------- /inspyred/ec/variators/__pycache__/crossovers.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/michstrauch/CoMOLA/HEAD/inspyred/ec/variators/__pycache__/crossovers.cpython-311.pyc -------------------------------------------------------------------------------- /models/SAR/.Rhistory: -------------------------------------------------------------------------------- 1 | library(here) 2 | install.packages(here) 3 | install.packages() here 4 | install.packages() 5 | install.packages('here') 6 | library(here) 7 | here 8 | here() 9 | -------------------------------------------------------------------------------- /input/transition_matrix.txt: -------------------------------------------------------------------------------- 1 | -2 1 2 3 4 5 6 7 8 2 | 1 1 1 1 1 1 1 1 0 3 | 2 1 1 1 1 1 1 1 0 4 | 3 1 1 1 1 1 1 1 0 5 | 4 1 1 1 1 1 1 1 0 6 | 5 1 1 1 1 1 1 1 0 7 | 6 0 0 0 0 0 1 1 0 8 | 7 0 0 0 0 0 0 1 0 9 | 8 0 0 0 0 0 0 0 1 10 | -------------------------------------------------------------------------------- /dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:latest 2 | 3 | ENV DEBIAN_FRONTEND=noninteractive 4 | RUN apt-get update && apt-get install -y --no-install-recommends r-base python3 python3-pip 5 | RUN python3 -m pip install matplotlib==3.7.1 6 | RUN python3 -m pip install numpy===1.24.3 7 | RUN R -e "install.packages('here')" 8 | WORKDIR /comola 9 | COPY . . 10 | CMD python3 __init__.py -------------------------------------------------------------------------------- /models/SYM/soil_fertility.asc: -------------------------------------------------------------------------------- 1 | ncols 10 2 | nrows 10 3 | xllcorner 4376461.4080843 4 | yllcorner 5553063.2189224 5 | cellsize 75 6 | NODATA_value -2 7 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 8 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 9 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 10 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 11 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 12 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 13 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 14 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 15 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 16 | 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 17 | -------------------------------------------------------------------------------- /inspyred/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This package allows the creation of bio-inspired computational intelligence algorithms. 3 | 4 | .. Copyright 2012 Inspired Intelligence Initiative 5 | 6 | .. This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | .. This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | .. You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | .. moduleauthor:: Aaron Garrett 20 | """ 21 | from inspyred import benchmarks 22 | from inspyred import ec 23 | from inspyred import swarm 24 | 25 | __all__ = ['benchmarks', 'ec', 'swarm'] 26 | __version__ = '1.0' 27 | __author__ = 'Aaron Garrett ' 28 | __url__ = 'http://inspyred.github.com' 29 | -------------------------------------------------------------------------------- /inspyred/swarm/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ================================== 3 | :mod:`swarm` -- Swarm intelligence 4 | ================================== 5 | 6 | This module provides standard swarm intelligence algorithms. 7 | 8 | .. Copyright 2012 Inspired Intelligence Initiative 9 | 10 | .. This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | .. This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | .. You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . 22 | 23 | .. moduleauthor:: Aaron Garrett 24 | """ 25 | from inspyred.swarm.swarm import ACS 26 | from inspyred.swarm.swarm import PSO 27 | from inspyred.swarm.swarm import TrailComponent 28 | import inspyred.swarm.topologies 29 | 30 | __all__ = ['ACS', 'PSO', 'TrailComponent', 'topologies'] 31 | -------------------------------------------------------------------------------- /inspyred/ec/variators/variators.py: -------------------------------------------------------------------------------- 1 | """ 2 | ================ 3 | :mod:`variators` 4 | ================ 5 | 6 | .. Copyright 2012 Inspired Intelligence Initiative 7 | 8 | .. This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | .. This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | .. You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | .. module:: variators 22 | .. moduleauthor:: Aaron Garrett 23 | """ 24 | 25 | 26 | def default_variation(random, candidates, args): 27 | """Return the set of candidates without variation. 28 | 29 | .. Arguments: 30 | random -- the random number generator object 31 | candidates -- the candidate solutions 32 | args -- a dictionary of keyword arguments 33 | 34 | """ 35 | return candidates 36 | 37 | -------------------------------------------------------------------------------- /inspyred/ec/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | =============================================== 3 | :mod:`ec` -- Evolutionary computation framework 4 | =============================================== 5 | 6 | This module provides a framework for creating evolutionary computations. 7 | 8 | .. Copyright 2012 Inspired Intelligence Initiative 9 | 10 | .. This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | .. This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | .. You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . 22 | 23 | .. moduleauthor:: Aaron Garrett 24 | """ 25 | from inspyred.ec.ec import Bounder 26 | from inspyred.ec.ec import DEA 27 | from inspyred.ec.ec import DiscreteBounder 28 | from inspyred.ec.ec import EDA 29 | from inspyred.ec.ec import Error 30 | from inspyred.ec.ec import ES 31 | from inspyred.ec.ec import EvolutionaryComputation 32 | from inspyred.ec.ec import EvolutionExit 33 | from inspyred.ec.ec import GA 34 | from inspyred.ec.ec import Individual 35 | from inspyred.ec.ec import SA 36 | import inspyred.ec.analysis 37 | import inspyred.ec.archivers 38 | import inspyred.ec.emo 39 | import inspyred.ec.evaluators 40 | import inspyred.ec.migrators 41 | import inspyred.ec.observers 42 | import inspyred.ec.replacers 43 | import inspyred.ec.selectors 44 | import inspyred.ec.terminators 45 | import inspyred.ec.utilities 46 | import inspyred.ec.variators 47 | 48 | __all__ = ['Bounder', 'DiscreteBounder', 'Individual', 'Error', 'EvolutionExit', 49 | 'EvolutionaryComputation', 'GA', 'ES', 'EDA', 'DEA', 'SA', 50 | 'analysis', 'archivers', 'emo', 'evaluators', 'migrators', 'observers', 51 | 'replacers', 'selectors', 'terminators', 'utilities', 'variators'] 52 | 53 | 54 | -------------------------------------------------------------------------------- /input/Helperscripts_for_Input/nws/landusefrompatchmap.R: -------------------------------------------------------------------------------- 1 | # 2 | # This Code generates a landusemap, patchmap and Soil-fertility-map based on 3 | # 1.patchmap 4 | # 2.soilfertility-map 5 | # 3.landuse_grid 6 | # given by ArcGis and makes them suitable for the optimasationprocess in CoMOLA 7 | 8 | here::i_am('landusefrompatchmap.R') 9 | library(here) 10 | library(raster) 11 | 12 | 13 | safelocation <- '/Users/victorsteffens/Documents/CoMOLA/CoMOLA_repo/COMOla/input' 14 | location <- here() 15 | landuse <- raster(paste(location,'nws_patch_id.asc', sep='/'),NAflag = -2, datatype = 'INT2U') 16 | landgrid <- read.table(paste(location, 'nws_grid_landuse.csv', sep='/'), header = T, sep =';', dec=',') 17 | soilfert <- raster(paste(location,'soil_fertility.asc', sep='/'),NAflag = -2, datatype = 'INT2U') 18 | 19 | # Find values for landuse by using landgrid 20 | landuseindices <- match(values(landuse), landgrid$grid_id) 21 | 22 | # Replace patchmapvalues with corresponding values from landgrid and nullify all 8-landuseclasses. Then write new landusemap. 23 | # Addiditionally adapt soilfertility-map 24 | values(landuse) <- landgrid$lu_code[landuseindices] 25 | 26 | values(landuse)[is.na(values(landuse))] <- -2 27 | 28 | nullsoilindices <- which(values(landuse) %in% -2) 29 | staticindices <- which(values(landuse) %in% 8) 30 | 31 | values(soilfert)[nullsoilindices] <- -2 32 | 33 | writeRaster(landuse, paste(location,'landusefrompatch.asc', sep='/'), overwrite = T, NAflag = -2, datatype = 'INT') 34 | writeRaster(soilfert, paste(location,'soilfertilityfrompatch.asc', sep='/'), overwrite = T) 35 | 36 | #Load patchmap again to create patchmap corresponding to landusemap: 37 | patchmap <- raster(paste(location,'nws_patch_id.asc', sep='/'),NAflag = -2, datatype = 'INT2U') 38 | #1)Nullify -2-Values and 8-Values 39 | #2)Build consecutive order for numbering of patches 40 | modlandgrid <- landgrid[!landgrid$lu_code=='-2',] 41 | modlandgrid <- modlandgrid[!modlandgrid$lu_code == '8',] 42 | modlandgrid <- modlandgrid[,-1] 43 | rownames.modlandgrid <- NULL 44 | #modlandgrid$FID <- c(1:nrow(modlandgrid)) 45 | orderpatchindices <- match(values(patchmap), modlandgrid$grid_id) 46 | 47 | values(patchmap) <- orderpatchindices 48 | values(patchmap)[staticindices] <- 0 49 | 50 | values(patchmap)[is.na(values(patchmap))] <- 0 51 | 52 | writeRaster(patchmap, paste(location,'newpatchfromoldpatch.asc', sep='/'), overwrite = T, NAflag = -2, datatype = 'INT') 53 | 54 | -------------------------------------------------------------------------------- /inspyred/ec/generators.py: -------------------------------------------------------------------------------- 1 | """ 2 | ================================================ 3 | :mod:`generators` -- Solution generation methods 4 | ================================================ 5 | 6 | Generator functions are problem-specific. They are used to create the 7 | initial set of candidate solutions needed by the evolutionary computation. 8 | 9 | All generator functions have the following arguments: 10 | 11 | - *random* -- the random number generator object 12 | - *args* -- a dictionary of keyword arguments 13 | 14 | .. Copyright 2012 Inspired Intelligence Initiative 15 | 16 | .. This program is free software: you can redistribute it and/or modify 17 | it under the terms of the GNU General Public License as published by 18 | the Free Software Foundation, either version 3 of the License, or 19 | (at your option) any later version. 20 | 21 | .. This program is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | .. You should have received a copy of the GNU General Public License 27 | along with this program. If not, see . 28 | 29 | .. module:: generators 30 | .. moduleauthor:: Aaron Garrett 31 | """ 32 | import functools 33 | 34 | 35 | def strategize(generator): 36 | """Add strategy parameters to candidates created by a generator. 37 | 38 | This function decorator is used to provide a means of adding strategy 39 | parameters to candidates created by a generator. The generator function 40 | is modifed to extend the candidate with ``len(candidate)`` strategy 41 | parameters (one per candidate element). Each strategy parameter is 42 | initialized to a random value in the range [0, 1]. The typical usage is 43 | as follows:: 44 | 45 | @strategize 46 | def generator_function(random, args): 47 | # Normal generator function 48 | pass 49 | 50 | """ 51 | @functools.wraps(generator) 52 | def strategy_generator(random, args): 53 | candidate = generator(random, args) 54 | n = len(candidate) 55 | candidate.extend([random.random() for _ in range(n)]) 56 | return candidate 57 | return strategy_generator 58 | 59 | 60 | class diversify(object): 61 | """Ensure uniqueness of candidates created by a generator. 62 | 63 | This function decorator is used to enforce uniqueness of candidates 64 | created by a generator. The decorator maintains a list of previously 65 | created candidates, and it ensures that new candidates are unique by 66 | checking a generated candidate against that list, regenerating if a 67 | duplicate is found. The typical usage is as follows:: 68 | 69 | @diversify 70 | def generator_function(random, args): 71 | # Normal generator function 72 | pass 73 | 74 | If a list of seeds is used, then these can be specified prior to the 75 | generator's use by saying the following:: 76 | 77 | @diversify 78 | def generator_function(random, args): 79 | # Normal generator function 80 | pass 81 | generator_function.candidates = seeds 82 | 83 | """ 84 | def __init__ (self, generator): 85 | self.candidates = [] 86 | self.generator = generator 87 | try: 88 | functools.update_wrapper(self, generator) 89 | except: 90 | pass 91 | 92 | def __call__ (self, random, args): 93 | c = self.generator(random, args) 94 | while c in self.candidates: 95 | c = self.generator(random, args) 96 | self.candidates.append(c) 97 | return c 98 | -------------------------------------------------------------------------------- /inspyred/swarm/topologies.py: -------------------------------------------------------------------------------- 1 | """ 2 | ===================================== 3 | :mod:`topologies` -- Swarm topologies 4 | ===================================== 5 | 6 | This module defines various topologies for swarm intelligence algorithms. 7 | 8 | Particle swarms make use of topologies, which determine the logical 9 | relationships among particles in the swarm (i.e., which ones belong to the same 10 | "neighborhood"). All topology functions have the following arguments: 11 | 12 | - *random* -- the random number generator object 13 | - *population* -- the population of Particles 14 | - *args* -- a dictionary of keyword arguments 15 | 16 | Each topology function returns a list of lists of neighbors 17 | for each particle in the population. For example, if a swarm 18 | contained 10 particles, then this function would return a list 19 | containing 10 lists, each of which contained the neighbors for 20 | its corresponding particle in the population. 21 | 22 | Rather than constructing and returning a list of lists directly, the 23 | topology functions could (and probably *should*, for efficiency) be 24 | written as generators that yield each neighborhood list one at a 25 | time. This is how the existing topology functions operate. 26 | 27 | .. Copyright 2012 Inspired Intelligence Initiative 28 | 29 | .. This program is free software: you can redistribute it and/or modify 30 | it under the terms of the GNU General Public License as published by 31 | the Free Software Foundation, either version 3 of the License, or 32 | (at your option) any later version. 33 | 34 | .. This program is distributed in the hope that it will be useful, 35 | but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 | GNU General Public License for more details. 38 | 39 | .. You should have received a copy of the GNU General Public License 40 | along with this program. If not, see . 41 | 42 | .. module:: topologies 43 | .. moduleauthor:: Aaron Garrett 44 | """ 45 | 46 | 47 | def star_topology(random, population, args): 48 | """Returns the neighbors using a star topology. 49 | 50 | This function sets all particles as neighbors for all other particles. 51 | This is known as a star topology. The resulting list of lists of 52 | neighbors is returned. 53 | 54 | .. Arguments: 55 | random -- the random number generator object 56 | population -- the population of particles 57 | args -- a dictionary of keyword arguments 58 | 59 | """ 60 | for _ in range(len(population)): 61 | yield population[:] 62 | 63 | 64 | def ring_topology(random, population, args): 65 | """Returns the neighbors using a ring topology. 66 | 67 | This function sets all particles in a specified sized neighborhood 68 | as neighbors for a given particle. This is known as a ring 69 | topology. The resulting list of lists of neighbors is returned. 70 | 71 | .. Arguments: 72 | random -- the random number generator object 73 | population -- the population of particles 74 | args -- a dictionary of keyword arguments 75 | 76 | Optional keyword arguments in args: 77 | 78 | - *neighborhood_size* -- the width of the neighborhood around a 79 | particle which determines the size of the neighborhood 80 | (default 3) 81 | 82 | """ 83 | neighborhood_size = args.setdefault('neighborhood_size', 3) 84 | half_hood = neighborhood_size // 2 85 | neighbor_index_start = [] 86 | for index in range(len(population)): 87 | if index < half_hood: 88 | neighbor_index_start.append(len(population) - half_hood + index) 89 | else: 90 | neighbor_index_start.append(index - half_hood) 91 | neighbors = [] 92 | for start in neighbor_index_start: 93 | n = [] 94 | for i in range(0, neighborhood_size): 95 | n.append(population[(start + i) % len(population)]) 96 | yield n 97 | 98 | -------------------------------------------------------------------------------- /requirements.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #------------------------------------------------------------------------------ 3 | # 4 | # Name: requirements.py 5 | # Purpose: This module is responsible for checking requirements of the tool. 6 | # 7 | # Author: Carola Paetzold 8 | # Contact: carola.paetzold@ufz.de 9 | # 10 | # Helmholtz Centre for Environmental Research - UFZ 11 | # Department Computational Landscape Ecology - CLE 12 | # Permoserstrasse 15 13 | # D-04318 Leipzig, Germany 14 | # http://www.ufz.de 15 | # 16 | # Created: Wed May 21 2014 17 | # 18 | # Copyright: (c) Carola Paetzold 2014 19 | # 20 | # Licence: This program is free software: 21 | # you can redistribute it and/or modify it under the terms 22 | # of the GNU General Public License as published by the 23 | # Free Software Foundation, either version 3 of the License, 24 | # or (at your option) any later version. This program is 25 | # distributed in the hope that it will be useful, but 26 | # WITHOUT ANY WARRANTY; without even the implied warranty 27 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 28 | # See the GNU General Public License for more details. 29 | # You should have received a copy of the GNU General 30 | # Public License along with this program. 31 | # If not, see . 32 | # 33 | #------------------------------------------------------------------------------ 34 | 35 | #------------------------------------------------------------------------------ 36 | # Imports 37 | #------------------------------------------------------------------------------ 38 | import os 39 | import sys 40 | import importlib 41 | import config as cfg 42 | 43 | #------------------------------------------------------------------------------ 44 | # Check the Python Version and requirements of the tool 45 | #------------------------------------------------------------------------------ 46 | def check_requirements(): 47 | # path to the used Python version 48 | python_folder = sys.executable 49 | accepted_versions = [(3,9),(3,10),(3,11)] 50 | # check for accepted python versions 51 | if not sys.version_info[:2] in accepted_versions: 52 | print ("Warning: The tool is testet for Python 3.11. You started the tool with Python version from %s." %python_folder) 53 | # check if the libraries matplotlib and RPy2 exist 54 | matplotlib_exist = importlib.util.find_spec("matplotlib") 55 | rpy2_exist = importlib.util.find_spec("rpy2") 56 | if not matplotlib_exist: 57 | if not rpy2_exist: 58 | print("Error, you need the matplotlib library but it is not installed in Python version from %s. If you would like to use RPy2 than you should install RPy2 too." %python_folder) 59 | else: 60 | print("Error, you need the matplotlib library but it is not installed in Python version from %s." %python_folder) 61 | close_window() 62 | # matplotlib exist, check if RPy2 is used and installed 63 | elif cfg.modelConfig.RPy2_available == "True" and not rpy2_exist: 64 | #if not rpy2_exist: 65 | print("Error, you want use RPy2 but it is not installed in Python version from %s." %python_folder) 66 | close_window() 67 | #------------------------------------------------------------------------------ 68 | # Close the program after a key entry 69 | #------------------------------------------------------------------------------ 70 | def close_window(): 71 | """Prevent that the window is closed after the error message appears.""" 72 | 73 | # wait for an input before close the window 74 | # the user can read the error messages 75 | # raw_input does not exist in Python 3 76 | #raw_input('Please press enter to close the program.') 77 | # Python 3 78 | input('Please press enter to close the program.') 79 | exit(1) 80 | 81 | #------------------------------------------------------------------------------ 82 | # 83 | # EOF 84 | # 85 | #------------------------------------------------------------------------------ 86 | -------------------------------------------------------------------------------- /inspyred/ec/migrators.py: -------------------------------------------------------------------------------- 1 | """ 2 | ============================================== 3 | :mod:`migrators` -- Solution migration methods 4 | ============================================== 5 | 6 | This module provides pre-defined migrators for evolutionary computations. 7 | 8 | All migrator functions have the following arguments: 9 | 10 | - *random* -- the random number generator object 11 | - *population* -- the population of Individuals 12 | - *args* -- a dictionary of keyword arguments 13 | 14 | Each migrator function returns the updated population. 15 | 16 | Migrator functions would typically be used for multi-population approaches, 17 | such as island-model evolutionary computations. They provide a means for 18 | individuals to be transferred from one population to another during the 19 | evolutionary process. 20 | 21 | .. Copyright 2012 Inspired Intelligence Initiative 22 | 23 | .. This program is free software: you can redistribute it and/or modify 24 | it under the terms of the GNU General Public License as published by 25 | the Free Software Foundation, either version 3 of the License, or 26 | (at your option) any later version. 27 | 28 | .. This program is distributed in the hope that it will be useful, 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 31 | GNU General Public License for more details. 32 | 33 | .. You should have received a copy of the GNU General Public License 34 | along with this program. If not, see . 35 | 36 | .. module:: migrators 37 | .. moduleauthor:: Aaron Garrett 38 | """ 39 | import multiprocessing 40 | try: 41 | import Queue 42 | except ImportError: 43 | import queue as Queue 44 | 45 | 46 | def default_migration(random, population, args): 47 | """Do nothing. 48 | 49 | This function just returns the existing population with no changes. 50 | 51 | """ 52 | return population 53 | 54 | 55 | class MultiprocessingMigrator(object): 56 | """Migrate among processes on the same machine. 57 | 58 | This callable class allows individuals to migrate from one process 59 | to another on the same machine. It maintains a queue of migrants 60 | whose maximum length can be fixed via the ``max_migrants`` 61 | parameter in the constructor. If the number of migrants in the queue 62 | reaches this value, new migrants are not added until earlier ones 63 | are consumed. The unreliability of a multiprocessing environment 64 | makes it difficult to provide guarantees. However, migrants are 65 | theoretically added and consumed at the same rate, so this value 66 | should determine the "freshness" of individuals, where smaller 67 | queue sizes provide more recency. 68 | 69 | An optional keyword argument in ``args`` requires the migrant to be 70 | evaluated by the current evolutionary computation before being inserted 71 | into the population. This can be important when different populations 72 | use different evaluation functions and you need to be able to compare 73 | "apples with apples," so to speak. 74 | 75 | Optional keyword arguments in args: 76 | 77 | - *evaluate_migrant* -- should new migrants be evaluated before 78 | adding them to the population (default False) 79 | 80 | """ 81 | def __init__(self, max_migrants=1): 82 | self.max_migrants = max_migrants 83 | self.migrants = multiprocessing.Queue(self.max_migrants) 84 | self._lock = multiprocessing.Lock() 85 | self.__name__ = self.__class__.__name__ 86 | 87 | def __call__(self, random, population, args): 88 | with self._lock: 89 | evaluate_migrant = args.setdefault('evaluate_migrant', False) 90 | migrant_index = random.randint(0, len(population) - 1) 91 | old_migrant = population[migrant_index] 92 | try: 93 | migrant = self.migrants.get(block=False) 94 | if evaluate_migrant: 95 | fit = args["_ec"].evaluator([migrant.candidate], args) 96 | migrant.fitness = fit[0] 97 | args["_ec"].num_evaluations += 1 98 | population[migrant_index] = migrant 99 | except Queue.Empty: 100 | pass 101 | try: 102 | self.migrants.put(old_migrant, block=False) 103 | except Queue.Full: 104 | pass 105 | return population 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [Dictionary] 2 | 3 | ; ----------------------------------------- 4 | ; config_model 5 | ; Variable Description: 6 | ; ---------- ------------ 7 | ; file_path_R | file path for R 8 | ; file_path_Python | file path for Python 9 | ; modelx_folder | file name of model x folder (1 <= x <= 4) 10 | ; file_modelx | file name of the model x script 11 | ; file_outputx | file name of the output file from model x 12 | ; update_filesx | file names which files of the model folder x 13 | ; should be updated in the helping folders 14 | ; max_range | maximum number of land use classes 15 | ; opt_algorithm (string) | definition of the optimization algorithm, 16 | ; available choices are GA or NSGA2 (default) 17 | ; RPy_available (string) | if RPy2 is available than True or False (default) 18 | ; map | if True individuals are printed as ascii map files into the 19 | ; model folders else (default) as vectors in a csv file 20 | ; del_help_folders | if True (default) delete and create all helping folders 21 | ; each time the tool starts, if False you can alternatively 22 | ; use the update_filex entries for updating important files 23 | ; some descr 24 | ; ----------------------------------------- 25 | ; config_optimization_algorithm 26 | ; Variable Description [default value]: 27 | ; ---------- ------------ 28 | ; pop_size | number of individuals per generation [100] 29 | ; max_generations | maximum number of generations [1] 30 | ; mutation_rate | probability for mutation [0.1] 31 | ; crossover_rate | probability for cross over [1.0] 32 | ; priority | land use from NSGA2 candidate is preferred within 33 | ; repair mutation [True] 34 | ; maximize | direction of optimization [True] 35 | ; extreme_seeds | generate extreme (but feasible) individuals for the first 36 | ; generation [False] 37 | ; max_repair_trials | maximum number of repair trials within repair mutation 38 | ; [10000] 39 | ; start_from_previous_gen | Start from the last saved generation [False] 40 | ; Assumning that there is no change in population size when starting from 41 | ; last saved generation individuals. 42 | ; terminator | termination criterion, see inspyred docu [default_termination] 43 | ; variator | variation method, see inspyred docu [default_variation] 44 | ; for constraint-handling and tabu-memory use repair_mutation 45 | ; selector | selection method, see inspyred docu [default_selection] 46 | ; use constrained_tournament_selection as alternative to 47 | ; repair_mutation 48 | ; feasible_first_pop | if True create feasible individuals for first population 49 | ; [False] 50 | ; penalty_function | 1 or 2 (only for constrained_tournament_selection) 51 | ; 1: absolute violation measure 52 | ; 2: normalized violation measure (default) 53 | ; plot_results | if True plot results into a .png file [False] 54 | ; ----------------------------------------- 55 | ; config_map_analysis 56 | ; Variable Description [default value]: 57 | ; ---------- ------------ 58 | ; file_landuse_map | file name of land use map [none] 59 | ; four_neighbours | analysis of four (True) or eight (False) cell neighbours 60 | ; | to generate patches [False] 61 | ; file_patch_map | file name of patch ID map [none] 62 | ; file_transition | file name of transition matrix [none] 63 | ; file_area | file name of total min-max area table [none] 64 | ; file_worst_fitness | file name of worst fitness values list [none] 65 | 66 | 67 | [config_model] 68 | 69 | file_path_R = C:/Program Files/R/R-4.4.2/bin/R.exe 70 | file_path_Python = C:/Users/marsh/AppData/Local/Programs/Python/Python311/python.exe 71 | 72 | model1_folder = HabStruct 73 | file_model1 = HabStruct.R 74 | file_output1 = HabStruct_output.csv 75 | 76 | model2_folder = SYM 77 | file_model2 = SYM.R 78 | file_output2 = SYM_output.csv 79 | 80 | model3_folder = WYLD 81 | file_model3 = WYLD.R 82 | file_output3 = WYLD_output.csv 83 | 84 | model4_folder = SAR 85 | file_model4 = SAR.R 86 | file_output4 = SAR_output.csv 87 | 88 | max_range = 8 89 | opt_algorithm = NSGA2 90 | RPy2_available = False 91 | map = True 92 | del_help_folders = True 93 | 94 | [config_optimization_algorithm] 95 | 96 | pop_size = 5 97 | max_generations = 5 98 | mutation_rate = 0.01 99 | crossover_rate = 0.9 100 | priority = True 101 | maximize = True 102 | extreme_seeds = False 103 | max_repair_trials = 10000 104 | start_from_previous_gen = False 105 | 106 | terminator = special_termination,generation_termination,diversity_termination 107 | variator = n_point_crossover, random_reset_mutation, repair_mutation 108 | ;variator = n_point_crossover, random_reset_mutation 109 | ;selector = constrained_tournament_selection 110 | feasible_first_pop = True 111 | ;penalty_function = 1 112 | ;plot_results = True 113 | 114 | [config_map_analysis] 115 | 116 | file_landuse_map = landusefrompatch.asc 117 | four_neighbours = True 118 | file_patch_map = newpatchfromoldpatch.asc 119 | file_transition = transition_matrix.txt 120 | ;file_area = min_max.txt 121 | file_worst_fitness = worst_fitness_values_maximize.txt -------------------------------------------------------------------------------- /inspyred/ec/variators/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | ============================================== 3 | :mod:`variators` -- Solution variation methods 4 | ============================================== 5 | 6 | This module provides pre-defined variators for evolutionary computations. 7 | 8 | All variator functions have the following arguments: 9 | 10 | - *random* -- the random number generator object 11 | - *candidates* -- the candidate solutions 12 | - *args* -- a dictionary of keyword arguments 13 | 14 | Each variator function returns the list of modified individuals. In 15 | the case of crossover variators, each pair of parents produces a pair 16 | of offspring. In the case of mutation variators, each candidate 17 | produces a single mutant. 18 | 19 | These variators may make some limited assumptions about the type of 20 | candidate solutions on which they operate. These assumptions are noted 21 | in the table below. First, all variators except for ``default_variation`` 22 | assume that the candidate solutions are ``Sequence`` types. Those marked 23 | under "Real" assume that candidates are composed of real numbers. Those 24 | marked "Binary" assume that candidates are composed entirely of 0's and 1's. 25 | Those marked "Discrete" assume that candidates are composed of elements 26 | from a discrete set where the ``DiscreteBounder`` has been used. And 27 | those marked "Pickle" assume that candidates can be pickled. 28 | 29 | .. tabularcolumns:: |l|c|c|c|c|c|c|c|c| 30 | 31 | +------------------------------+----------+------+--------+----------+--------+ 32 | | Variator | Sequence | Real | Binary | Discrete | Pickle | 33 | +==============================+==========+======+========+==========+========+ 34 | | default_variation | | | | | | 35 | +------------------------------+----------+------+--------+----------+--------+ 36 | | arithmetic_crossover | X | X | | | | 37 | +------------------------------+----------+------+--------+----------+--------+ 38 | | blend_crossover | X | X | | | | 39 | +------------------------------+----------+------+--------+----------+--------+ 40 | | heuristic_crossover | X | X | | | X | 41 | +------------------------------+----------+------+--------+----------+--------+ 42 | | laplace_crossover | X | X | | | | 43 | +------------------------------+----------+------+--------+----------+--------+ 44 | | n_point_crossover | X | | | | | 45 | +------------------------------+----------+------+--------+----------+--------+ 46 | | partially_matched_crossover | X | | | X | | 47 | +------------------------------+----------+------+--------+----------+--------+ 48 | | simulated_binary_crossover | X | X | | | | 49 | +------------------------------+----------+------+--------+----------+--------+ 50 | | uniform_crossover | X | | | | | 51 | +------------------------------+----------+------+--------+----------+--------+ 52 | | bit_flip_mutation | X | | X | | | 53 | +------------------------------+----------+------+--------+----------+--------+ 54 | | gaussian_mutation | X | X | | | | 55 | +------------------------------+----------+------+--------+----------+--------+ 56 | | inversion_mutation | X | | | | | 57 | +------------------------------+----------+------+--------+----------+--------+ 58 | | nonuniform_mutation | X | X | | | | 59 | +------------------------------+----------+------+--------+----------+--------+ 60 | | random_reset_mutation | X | | | X | | 61 | +------------------------------+----------+------+--------+----------+--------+ 62 | | scramble_mutation | X | | | | | 63 | +------------------------------+----------+------+--------+----------+--------+ 64 | 65 | .. Copyright 2012 Inspired Intelligence Initiative 66 | 67 | .. This program is free software: you can redistribute it and/or modify 68 | it under the terms of the GNU General Public License as published by 69 | the Free Software Foundation, either version 3 of the License, or 70 | (at your option) any later version. 71 | 72 | .. This program is distributed in the hope that it will be useful, 73 | but WITHOUT ANY WARRANTY; without even the implied warranty of 74 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 75 | GNU General Public License for more details. 76 | 77 | .. You should have received a copy of the GNU General Public License 78 | along with this program. If not, see . 79 | 80 | .. moduleauthor:: Aaron Garrett 81 | """ 82 | from inspyred.ec.variators.variators import default_variation 83 | from inspyred.ec.variators.crossovers import crossover 84 | from inspyred.ec.variators.crossovers import arithmetic_crossover 85 | from inspyred.ec.variators.crossovers import blend_crossover 86 | from inspyred.ec.variators.crossovers import heuristic_crossover 87 | from inspyred.ec.variators.crossovers import laplace_crossover 88 | from inspyred.ec.variators.crossovers import n_point_crossover 89 | from inspyred.ec.variators.crossovers import partially_matched_crossover 90 | from inspyred.ec.variators.crossovers import simulated_binary_crossover 91 | from inspyred.ec.variators.crossovers import uniform_crossover 92 | from inspyred.ec.variators.mutators import mutator 93 | from inspyred.ec.variators.mutators import bit_flip_mutation 94 | from inspyred.ec.variators.mutators import gaussian_mutation 95 | from inspyred.ec.variators.mutators import inversion_mutation 96 | from inspyred.ec.variators.mutators import nonuniform_mutation 97 | from inspyred.ec.variators.mutators import random_reset_mutation 98 | from inspyred.ec.variators.mutators import scramble_mutation 99 | # author: Carola Paetzold 100 | from inspyred.ec.variators.mutators import filter_mutation 101 | from inspyred.ec.variators.mutators import repair_mutation 102 | 103 | __all__ = ['default_variation', 104 | 'crossover', 'arithmetic_crossover', 'blend_crossover', 'heuristic_crossover', 105 | 'laplace_crossover', 'n_point_crossover', 'partially_matched_crossover', 106 | 'simulated_binary_crossover', 'uniform_crossover', 107 | 'mutator', 'bit_flip_mutation', 'gaussian_mutation', 'inversion_mutation', 108 | 'nonuniform_mutation', 'random_reset_mutation', 'scramble_mutation', 'filter_mutation', 'repair_mutation'] 109 | -------------------------------------------------------------------------------- /inspyred/ec/utilities.py: -------------------------------------------------------------------------------- 1 | """ 2 | ================================================== 3 | :mod:`utilities` -- Optimization utility functions 4 | ================================================== 5 | 6 | This module provides utility classes and decorators for evolutionary computations. 7 | 8 | .. Copyright 2012 Inspired Intelligence Initiative 9 | 10 | .. This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | .. This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | .. You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . 22 | 23 | .. module:: utilities 24 | .. moduleauthor:: Aaron Garrett 25 | """ 26 | import collections 27 | import functools 28 | import multiprocessing 29 | try: 30 | import cPickle as pickle 31 | except ImportError: 32 | import pickle 33 | 34 | 35 | class BoundedOrderedDict(collections.OrderedDict): 36 | def __init__(self, *args, **kwds): 37 | self._lock = multiprocessing.Lock() 38 | self.maxlen = kwds.pop("maxlen", None) 39 | collections.OrderedDict.__init__(self, *args, **kwds) 40 | self._checklen() 41 | 42 | def __setitem__(self, key, value): 43 | with self._lock: 44 | collections.OrderedDict.__setitem__(self, key, value) 45 | self._checklen() 46 | 47 | def _checklen(self): 48 | if self.maxlen is not None: 49 | while len(self) > self.maxlen: 50 | self.popitem(last=False) 51 | 52 | 53 | def memoize(func=None, maxlen=None): 54 | """Cache a function's return value each time it is called. 55 | 56 | This function serves as a function decorator to provide a caching of 57 | evaluated fitness values. If called later with the same arguments, 58 | the cached value is returned instead of being re-evaluated. 59 | 60 | This decorator assumes that candidates are individually pickleable, 61 | and their pickled values are used for hashing into a dictionary. It 62 | should be used when evaluating an *expensive* fitness 63 | function to avoid costly re-evaluation of those fitnesses. The 64 | typical usage is as follows:: 65 | 66 | @memoize 67 | def expensive_fitness_function(candidates, args): 68 | # Implementation of expensive fitness calculation 69 | pass 70 | 71 | It is also possible to provide the named argument *maxlen*, which 72 | specifies the size of the memoization cache to use. (If *maxlen* is 73 | ``None``, then an unbounded cache is used.) Once the size of the cache 74 | has reached *maxlen*, the oldest element is replaced by the newest 75 | element in order to keep the size constant. This usage is as follows:: 76 | 77 | @memoize(maxlen=100) 78 | def expensive_fitness_function(candidates, args): 79 | # Implementation of expensive fitness calculation 80 | pass 81 | 82 | .. warning:: The ``maxlen`` parameter must be passed as a named keyword 83 | argument, or an ``AttributeError`` will be raised (e.g., saying 84 | ``@memoize(100)`` will cause an error). 85 | 86 | """ 87 | if func is not None: 88 | cache = BoundedOrderedDict(maxlen=maxlen) 89 | @functools.wraps(func) 90 | def memo_target(candidates, args): 91 | fitness = [] 92 | for candidate in candidates: 93 | lookup_value = pickle.dumps(candidate, 1) 94 | if lookup_value not in cache: 95 | cache[lookup_value] = func([candidate], args)[0] 96 | fitness.append(cache[lookup_value]) 97 | return fitness 98 | return memo_target 99 | else: 100 | def memoize_factory(func): 101 | return memoize(func, maxlen=maxlen) 102 | return memoize_factory 103 | 104 | 105 | class Objectify(object): 106 | """Create an "objectified" version of a function. 107 | 108 | This function allows an ordinary function passed to it to 109 | become essentially a callable instance of a class. For inspyred, 110 | this means that evolutionary operators (selectors, variators, 111 | replacers, etc.) can be created as normal functions and then 112 | be given the ability to have attributes *that are specific to 113 | the object*. Python functions can always have attributes without 114 | employing any special mechanism, but those attributes exist for the 115 | function, and there is no way to create a new "object" except 116 | by implementing a new function with the same functionality. 117 | This class provides a way to "objectify" the same function 118 | multiple times in order to provide each "object" with its own 119 | set of independent attributes. 120 | 121 | The attributes that are created on an objectified function are 122 | passed into that function via the ubiquitous ``args`` variable 123 | in inspyred. Any user-specified attributes are added to the 124 | ``args`` dictionary and replace any existing entry if necessary. 125 | If the function modifies those entries in the dictionary (e.g., 126 | when dynamically modifying parameters), the corresponding 127 | attributes are modified as well. 128 | 129 | Essentially, a local copy of the ``args`` dictionary is created 130 | into which the attributes are inserted. This modified local copy 131 | is then passed to the function. After the function returns, the 132 | values of the attributes from the dictionary are retrieved and 133 | are used to update the class attributes. 134 | 135 | The typical usage is as follows:: 136 | 137 | def typical_function(*args, **kwargs): 138 | # Implementation of typical function 139 | pass 140 | 141 | fun_one = Objectify(typical_function) 142 | fun_two = Objectify(typical_function) 143 | fun_one.attribute = value_one 144 | fun_two.attribute = value_two 145 | 146 | """ 147 | def __init__(self, func): 148 | self.func = func 149 | try: 150 | functools.update_wrapper(self, func) 151 | except: 152 | pass 153 | 154 | def __call__(self, *args, **kwargs): 155 | params = vars(self) 156 | try: 157 | orig_args = dict(kwargs['args']) 158 | orig_args.update(params) 159 | newkwargs = dict(kwargs) 160 | newkwargs['args'] = orig_args 161 | newargs = args 162 | except KeyError: 163 | orig_args = dict(args[-1]) 164 | orig_args.update(params) 165 | newargs = list(args[:-1]) 166 | newargs.append(orig_args) 167 | newargs = tuple(newargs) 168 | newkwargs = kwargs 169 | return_value = self.func(*newargs, **newkwargs) 170 | try: 171 | for key in newkwargs['args']: 172 | if key in params: 173 | setattr(self, key, newkwargs['args'][key]) 174 | except KeyError: 175 | for key in newargs[-1]: 176 | if key in params: 177 | setattr(self, key, newargs[-1][key]) 178 | return return_value 179 | -------------------------------------------------------------------------------- /inspyred/ec/emo.py: -------------------------------------------------------------------------------- 1 | """ 2 | ====================================================== 3 | :mod:`emo` -- Evolutionary multiobjective optimization 4 | ====================================================== 5 | 6 | This module provides the framework for making multiobjective evolutionary 7 | computations. 8 | 9 | .. Copyright 2012 Inspired Intelligence Initiative 10 | 11 | .. This program is free software: you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation, either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | .. This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | .. You should have received a copy of the GNU General Public License 22 | along with this program. If not, see . 23 | 24 | .. module:: emo 25 | .. moduleauthor:: Aaron Garrett 26 | """ 27 | from inspyred.ec import ec 28 | import math 29 | 30 | 31 | class Pareto(object): 32 | """Represents a Pareto multiobjective solution. 33 | 34 | A Pareto solution is a set of multiobjective values that can be 35 | compared to other Pareto values using Pareto preference. This means 36 | that a solution dominates, or is better than, another solution if it 37 | is better than or equal to the other solution in all objectives and 38 | strictly better in at least one objective. 39 | 40 | Since some problems may mix maximization and minimization among 41 | different objectives, an optional `maximize` parameter may be 42 | passed upon construction of the Pareto object. This parameter 43 | may be a list of Booleans of the same length as the set of 44 | objective values. If this parameter is used, then the `maximize` 45 | parameter of the evolutionary computation's ``evolve`` method 46 | should be left as the default True value in order to avoid 47 | confusion. (Setting the `evolve`'s parameter to False would 48 | essentially invert all of the Booleans in the Pareto `maximize` 49 | list.) So, if all objectives are of the same type (either 50 | maximization or minimization), then it is best simply to use 51 | the `maximize` parameter of the `evolve` method and to leave 52 | the `maximize` parameter of the Pareto initialization set to 53 | its default True value. However, if the objectives are mixed 54 | maximization and minimization, it is best to leave the ``evolve``'s 55 | `maximize` parameter set to its default True value and specify 56 | the Pareto's `maximize` list to the appropriate Booleans. 57 | 58 | The typical usage is as follows:: 59 | 60 | @inspyred.ec.evaluators.evaluator 61 | def my_evaluator(candidate, args): 62 | obj1 = 1 # Calculate objective 1 63 | obj2 = 2 # Calculate objective 2 64 | obj3 = 3 # Calculate objective 3 65 | return emo.Pareto([obj1, obj2, obj3]) 66 | 67 | """ 68 | def __init__(self, values=None, maximize=True): 69 | if values is None: 70 | values = [] 71 | self.values = values 72 | try: 73 | iter(maximize) 74 | except TypeError: 75 | maximize = [maximize for v in values] 76 | self.maximize = maximize 77 | 78 | def __len__(self): 79 | return len(self.values) 80 | 81 | def __getitem__(self, key): 82 | return self.values[key] 83 | 84 | def __iter__(self): 85 | return iter(self.values) 86 | 87 | def __lt__(self, other): 88 | if len(self.values) != len(other.values): 89 | raise NotImplementedError 90 | else: 91 | not_worse = True 92 | strictly_better = False 93 | for x, y, m in zip(self.values, other.values, self.maximize): 94 | if m: 95 | if x > y: 96 | not_worse = False 97 | elif y > x: 98 | strictly_better = True 99 | else: 100 | if x < y: 101 | not_worse = False 102 | elif y < x: 103 | strictly_better = True 104 | return not_worse and strictly_better 105 | 106 | def __le__(self, other): 107 | return self < other or not other < self 108 | 109 | def __gt__(self, other): 110 | return other < self 111 | 112 | def __ge__(self, other): 113 | return other < self or not self < other 114 | 115 | def __eq__(self, other): 116 | return self.values == other.values 117 | 118 | def __ne__(self, other): 119 | return not (self == other) 120 | 121 | def __str__(self): 122 | return str(self.values) 123 | 124 | def __repr__(self): 125 | return str(self.values) 126 | 127 | 128 | class NSGA2(ec.EvolutionaryComputation): 129 | """Evolutionary computation representing the nondominated sorting genetic algorithm. 130 | 131 | This class represents the nondominated sorting genetic algorithm (NSGA-II) 132 | of Kalyanmoy Deb et al. It uses nondominated sorting with crowding for 133 | replacement, binary tournament selection to produce *population size* 134 | children, and a Pareto archival strategy. The remaining operators take 135 | on the typical default values but they may be specified by the designer. 136 | 137 | """ 138 | def __init__(self, random): 139 | ec.EvolutionaryComputation.__init__(self, random) 140 | self.archiver = ec.archivers.best_archiver 141 | self.replacer = ec.replacers.nsga_replacement 142 | self.selector = ec.selectors.tournament_selection 143 | 144 | def evolve(self, generator, evaluator, pop_size=100, seeds=None, maximize=True, bounder=None, is_available = None, custom_individual= [],archive = None, num_generation= 0 , **args): 145 | args.setdefault('num_selected', pop_size) 146 | args.setdefault('tournament_size', 2) 147 | previous_arc = archive 148 | return ec.EvolutionaryComputation.evolve(self, generator, evaluator, pop_size, seeds, maximize, bounder, is_available, custom_individual, previous_arc, num_generation, **args) 149 | 150 | 151 | class PAES(ec.EvolutionaryComputation): 152 | """Evolutionary computation representing the Pareto Archived Evolution Strategy. 153 | 154 | This class represents the Pareto Archived Evolution Strategy of Joshua 155 | Knowles and David Corne. It is essentially a (1+1)-ES with an adaptive 156 | grid archive that is used as a part of the replacement process. 157 | 158 | """ 159 | def __init__(self, random): 160 | ec.EvolutionaryComputation.__init__(self, random) 161 | self.archiver = ec.archivers.adaptive_grid_archiver 162 | self.selector = ec.selectors.default_selection 163 | self.variator = ec.variators.gaussian_mutation 164 | self.replacer = ec.replacers.paes_replacement 165 | 166 | def evolve(self, generator, evaluator, pop_size=1, seeds=None, maximize=True, bounder=None, **args): 167 | final_pop = ec.EvolutionaryComputation.evolve(self, generator, evaluator, pop_size, seeds, maximize, bounder, **args) 168 | try: 169 | del self.archiver.grid_population 170 | except AttributeError: 171 | pass 172 | try: 173 | del self.archiver.global_smallest 174 | except AttributeError: 175 | pass 176 | try: 177 | del self.archiver.global_largest 178 | except AttributeError: 179 | pass 180 | return final_pop 181 | 182 | 183 | -------------------------------------------------------------------------------- /inspyred/ec/evaluators.py: -------------------------------------------------------------------------------- 1 | """ 2 | =============================================== 3 | :mod:`evaluators` -- Fitness evaluation methods 4 | =============================================== 5 | 6 | Evaluator functions are problem-specific. This module provides pre-defined 7 | evaluators for evolutionary computations. 8 | 9 | All evaluator functions have the following arguments: 10 | 11 | - *candidates* -- the candidate solutions 12 | - *args* -- a dictionary of keyword arguments 13 | 14 | .. Copyright 2012 Inspired Intelligence Initiative 15 | 16 | .. This program is free software: you can redistribute it and/or modify 17 | it under the terms of the GNU General Public License as published by 18 | the Free Software Foundation, either version 3 of the License, or 19 | (at your option) any later version. 20 | 21 | .. This program is distributed in the hope that it will be useful, 22 | but WITHOUT ANY WARRANTY; without even the implied warranty of 23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 | GNU General Public License for more details. 25 | 26 | .. You should have received a copy of the GNU General Public License 27 | along with this program. If not, see . 28 | 29 | .. module:: evaluators 30 | .. moduleauthor:: Aaron Garrett 31 | .. moduleauthor:: Jelle Feringa 32 | """ 33 | import functools 34 | try: 35 | import cPickle as pickle 36 | except ImportError: 37 | import pickle 38 | 39 | 40 | def evaluator(evaluate): 41 | """Return an inspyred evaluator function based on the given function. 42 | 43 | This function generator takes a function that evaluates only one 44 | candidate. The generator handles the iteration over each candidate 45 | to be evaluated. 46 | 47 | The given function ``evaluate`` must have the following signature:: 48 | 49 | fitness = evaluate(candidate, args) 50 | 51 | This function is most commonly used as a function decorator with 52 | the following usage:: 53 | 54 | @evaluator 55 | def evaluate(candidate, args): 56 | # Implementation of evaluation 57 | pass 58 | 59 | The generated function also contains an attribute named 60 | ``single_evaluation`` which holds the original evaluation function. 61 | In this way, the original single-candidate function can be 62 | retrieved if necessary. 63 | 64 | """ 65 | @functools.wraps(evaluate) 66 | def ecspy_evaluator(candidates, args): 67 | fitness = [] 68 | for candidate in candidates: 69 | fitness.append(evaluate(candidate, args)) 70 | return fitness 71 | ecspy_evaluator.single_evaluation = evaluate 72 | return ecspy_evaluator 73 | 74 | 75 | def parallel_evaluation_pp(candidates, args): 76 | """Evaluate the candidates in parallel using Parallel Python. 77 | 78 | This function allows parallel evaluation of candidate solutions. 79 | It uses the `Parallel Python `_ (pp) 80 | library to accomplish the parallelization. This library must already 81 | be installed in order to use this function. The function assigns the 82 | evaluation of each candidate to its own job, all of which are then 83 | distributed to the available processing units. 84 | 85 | .. note:: 86 | 87 | All arguments to the evaluation function must be pickleable. 88 | Those that are not will not be sent through the ``args`` variable 89 | and will be unavailable to your function. 90 | 91 | .. Arguments: 92 | candidates -- the candidate solutions 93 | args -- a dictionary of keyword arguments 94 | 95 | Required keyword arguments in args: 96 | 97 | - *pp_evaluator* -- actual evaluation function to be used (This function 98 | should have the same signature as any other inspyred evaluation function.) 99 | 100 | Optional keyword arguments in args: 101 | 102 | - *pp_dependencies* -- tuple of functional dependencies of the serial 103 | evaluator (default ()) 104 | - *pp_modules* -- tuple of modules that must be imported for the 105 | functional dependencies (default ()) 106 | - *pp_servers* -- tuple of servers (on a cluster) that will be used 107 | for parallel processing (default ("*",)) 108 | - *pp_secret* -- string representing the secret key needed to authenticate 109 | on a worker node (default "inspyred") 110 | - *pp_nprocs* -- integer representing the number of worker processes to 111 | start on the local machine (default "autodetect", which sets it to the 112 | number of processors in the system) 113 | 114 | For more information about these arguments, please consult the 115 | documentation for `Parallel Python `_. 116 | 117 | """ 118 | import pp 119 | logger = args['_ec'].logger 120 | 121 | try: 122 | evaluator = args['pp_evaluator'] 123 | except KeyError: 124 | logger.error('parallel_evaluation_pp requires \'pp_evaluator\' be defined in the keyword arguments list') 125 | raise 126 | secret_key = args.setdefault('pp_secret', 'inspyred') 127 | try: 128 | job_server = args['_pp_job_server'] 129 | except KeyError: 130 | pp_servers = args.get('pp_servers', ("*",)) 131 | pp_nprocs = args.get('pp_nprocs', 'autodetect') 132 | job_server = pp.Server(ncpus=pp_nprocs, ppservers=pp_servers, secret=secret_key) 133 | args['_pp_job_server'] = job_server 134 | pp_depends = args.setdefault('pp_dependencies', ()) 135 | pp_modules = args.setdefault('pp_modules', ()) 136 | 137 | pickled_args = {} 138 | for key in args: 139 | try: 140 | pickle.dumps(args[key]) 141 | pickled_args[key] = args[key] 142 | except (TypeError, pickle.PickleError, pickle.PicklingError): 143 | logger.debug('unable to pickle args parameter {0} in parallel_evaluation_pp'.format(key)) 144 | pass 145 | 146 | func_template = pp.Template(job_server, evaluator, pp_depends, pp_modules) 147 | jobs = [func_template.submit([c], pickled_args) for c in candidates] 148 | 149 | fitness = [] 150 | for i, job in enumerate(jobs): 151 | r = job() 152 | try: 153 | fitness.append(r[0]) 154 | except TypeError: 155 | logger.warning('parallel_evaluation_pp generated an invalid fitness for candidate {0}'.format(candidates[i])) 156 | fitness.append(None) 157 | return fitness 158 | 159 | 160 | def parallel_evaluation_mp(candidates, args): 161 | """Evaluate the candidates in parallel using ``multiprocessing``. 162 | 163 | This function allows parallel evaluation of candidate solutions. 164 | It uses the standard multiprocessing library to accomplish the 165 | parallelization. The function assigns the evaluation of each 166 | candidate to its own job, all of which are then distributed to the 167 | available processing units. 168 | 169 | .. note:: 170 | 171 | All arguments to the evaluation function must be pickleable. 172 | Those that are not will not be sent through the ``args`` variable 173 | and will be unavailable to your function. 174 | 175 | .. Arguments: 176 | candidates -- the candidate solutions 177 | args -- a dictionary of keyword arguments 178 | 179 | Required keyword arguments in args: 180 | 181 | - *mp_evaluator* -- actual evaluation function to be used (This function 182 | should have the same signature as any other inspyred evaluation function.) 183 | 184 | Optional keyword arguments in args: 185 | 186 | - *mp_nprocs* -- number of processors that will be used (default machine 187 | cpu count) 188 | 189 | """ 190 | import time 191 | import multiprocessing 192 | logger = args['_ec'].logger 193 | 194 | try: 195 | evaluator = args['mp_evaluator'] 196 | except KeyError: 197 | logger.error('parallel_evaluation_mp requires \'mp_evaluator\' be defined in the keyword arguments list') 198 | raise 199 | try: 200 | nprocs = args['mp_nprocs'] 201 | except KeyError: 202 | nprocs = multiprocessing.cpu_count() 203 | 204 | pickled_args = {} 205 | for key in args: 206 | try: 207 | pickle.dumps(args[key]) 208 | pickled_args[key] = args[key] 209 | except (TypeError, pickle.PickleError, pickle.PicklingError): 210 | logger.debug('unable to pickle args parameter {0} in parallel_evaluation_mp'.format(key)) 211 | pass 212 | 213 | start = time.time() 214 | try: 215 | pool = multiprocessing.Pool(processes=nprocs) 216 | results = [pool.apply_async(evaluator, ([c], pickled_args)) for c in candidates] 217 | pool.close() 218 | pool.join() 219 | return [r.get()[0] for r in results] 220 | except (OSError, RuntimeError) as e: 221 | logger.error('failed parallel_evaluation_mp: {0}'.format(str(e))) 222 | raise 223 | else: 224 | end = time.time() 225 | logger.debug('completed parallel_evaluation_mp in {0} seconds'.format(end - start)) 226 | 227 | -------------------------------------------------------------------------------- /models/SAR/genom.csv: -------------------------------------------------------------------------------- 1 | genom 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 7 | 6 8 | 7 9 | 3 10 | 2 11 | 3 12 | 3 13 | 3 14 | 3 15 | 3 16 | 3 17 | 3 18 | 3 19 | 3 20 | 3 21 | 3 22 | 3 23 | 3 24 | 3 25 | 3 26 | 3 27 | 3 28 | 3 29 | 3 30 | 3 31 | 3 32 | 3 33 | 3 34 | 3 35 | 3 36 | 3 37 | 3 38 | 3 39 | 3 40 | 3 41 | 3 42 | 3 43 | 3 44 | 3 45 | 3 46 | 7 47 | 3 48 | 3 49 | 3 50 | 3 51 | 3 52 | 3 53 | 3 54 | 3 55 | 2 56 | 3 57 | 6 58 | 3 59 | 3 60 | 3 61 | 3 62 | 3 63 | 3 64 | 3 65 | 3 66 | 3 67 | 3 68 | 3 69 | 3 70 | 3 71 | 3 72 | 3 73 | 3 74 | 3 75 | 3 76 | 3 77 | 3 78 | 3 79 | 3 80 | 3 81 | 3 82 | 3 83 | 3 84 | 3 85 | 3 86 | 3 87 | 3 88 | 3 89 | 3 90 | 3 91 | 3 92 | 3 93 | 3 94 | 3 95 | 3 96 | 3 97 | 3 98 | 3 99 | 3 100 | 3 101 | 3 102 | 3 103 | 3 104 | 3 105 | 3 106 | 3 107 | 3 108 | 3 109 | 3 110 | 3 111 | 3 112 | 6 113 | 3 114 | 3 115 | 3 116 | 3 117 | 3 118 | 3 119 | 6 120 | 6 121 | 3 122 | 3 123 | 3 124 | 3 125 | 3 126 | 3 127 | 3 128 | 6 129 | 7 130 | 3 131 | 3 132 | 3 133 | 3 134 | 6 135 | 3 136 | 3 137 | 3 138 | 3 139 | 6 140 | 7 141 | 6 142 | 3 143 | 3 144 | 3 145 | 6 146 | 6 147 | 3 148 | 3 149 | 3 150 | 3 151 | 7 152 | 3 153 | 7 154 | 3 155 | 3 156 | 3 157 | 3 158 | 3 159 | 3 160 | 6 161 | 3 162 | 3 163 | 3 164 | 3 165 | 3 166 | 3 167 | 7 168 | 7 169 | 3 170 | 3 171 | 3 172 | 3 173 | 3 174 | 3 175 | 7 176 | 6 177 | 3 178 | 3 179 | 3 180 | 3 181 | 3 182 | 3 183 | 3 184 | 3 185 | 7 186 | 3 187 | 3 188 | 3 189 | 3 190 | 3 191 | 3 192 | 3 193 | 3 194 | 3 195 | 3 196 | 3 197 | 3 198 | 3 199 | 3 200 | 3 201 | 6 202 | 6 203 | 3 204 | 3 205 | 3 206 | 3 207 | 3 208 | 3 209 | 3 210 | 3 211 | 7 212 | 6 213 | 3 214 | 3 215 | 3 216 | 3 217 | 3 218 | 3 219 | 3 220 | 3 221 | 7 222 | 3 223 | 3 224 | 3 225 | 3 226 | 3 227 | 3 228 | 3 229 | 3 230 | 3 231 | 3 232 | 3 233 | 3 234 | 3 235 | 3 236 | 3 237 | 3 238 | 3 239 | 3 240 | 3 241 | 7 242 | 3 243 | 3 244 | 3 245 | 3 246 | 3 247 | 3 248 | 3 249 | 3 250 | 3 251 | 3 252 | 3 253 | 3 254 | 3 255 | 3 256 | 3 257 | 3 258 | 3 259 | 3 260 | 3 261 | 3 262 | 3 263 | 3 264 | 3 265 | 3 266 | 3 267 | 3 268 | 3 269 | 3 270 | 3 271 | 3 272 | 3 273 | 3 274 | 3 275 | 3 276 | 3 277 | 3 278 | 7 279 | 3 280 | 3 281 | 3 282 | 3 283 | 3 284 | 3 285 | 3 286 | 3 287 | 6 288 | 3 289 | 3 290 | 3 291 | 3 292 | 3 293 | 3 294 | 3 295 | 3 296 | 3 297 | 3 298 | 3 299 | 3 300 | 3 301 | 3 302 | 3 303 | 3 304 | 3 305 | 6 306 | 3 307 | 3 308 | 3 309 | 3 310 | 3 311 | 3 312 | 3 313 | 3 314 | 3 315 | 6 316 | 3 317 | 3 318 | 3 319 | 3 320 | 3 321 | 3 322 | 3 323 | 3 324 | 3 325 | 6 326 | 3 327 | 3 328 | 3 329 | 3 330 | 3 331 | 3 332 | 3 333 | 3 334 | 3 335 | 3 336 | 3 337 | 7 338 | 3 339 | 3 340 | 3 341 | 3 342 | 3 343 | 3 344 | 3 345 | 3 346 | 3 347 | 3 348 | 3 349 | 3 350 | 3 351 | 3 352 | 3 353 | 3 354 | 3 355 | 3 356 | 3 357 | 3 358 | 3 359 | 7 360 | 3 361 | 3 362 | 3 363 | 3 364 | 3 365 | 3 366 | 3 367 | 3 368 | 3 369 | 3 370 | 6 371 | 3 372 | 3 373 | 3 374 | 3 375 | 3 376 | 3 377 | 3 378 | 3 379 | 3 380 | 3 381 | 5 382 | 3 383 | 3 384 | 6 385 | 3 386 | 3 387 | 3 388 | 3 389 | 3 390 | 3 391 | 3 392 | 3 393 | 3 394 | 3 395 | 3 396 | 6 397 | 3 398 | 3 399 | 3 400 | 3 401 | 3 402 | 3 403 | 3 404 | 3 405 | 3 406 | 3 407 | 3 408 | 6 409 | 3 410 | 3 411 | 3 412 | 3 413 | 1 414 | 3 415 | 3 416 | 3 417 | 3 418 | 3 419 | 3 420 | 3 421 | 7 422 | 3 423 | 3 424 | 7 425 | 3 426 | 3 427 | 3 428 | 3 429 | 3 430 | 3 431 | 3 432 | 3 433 | 3 434 | 3 435 | 3 436 | 3 437 | 3 438 | 7 439 | 3 440 | 3 441 | 3 442 | 3 443 | 3 444 | 3 445 | 3 446 | 3 447 | 3 448 | 3 449 | 3 450 | 3 451 | 3 452 | 3 453 | 3 454 | 3 455 | 3 456 | 3 457 | 3 458 | 3 459 | 3 460 | 3 461 | 3 462 | 3 463 | 3 464 | 3 465 | 3 466 | 7 467 | 3 468 | 3 469 | 3 470 | 3 471 | 3 472 | 3 473 | 3 474 | 3 475 | 3 476 | 3 477 | 3 478 | 3 479 | 3 480 | 3 481 | 3 482 | 3 483 | 3 484 | 3 485 | 3 486 | 3 487 | 3 488 | 3 489 | 3 490 | 3 491 | 3 492 | 3 493 | 3 494 | 3 495 | 3 496 | 3 497 | 7 498 | 3 499 | 3 500 | 3 501 | 3 502 | 3 503 | 3 504 | 3 505 | 3 506 | 3 507 | 3 508 | 7 509 | 3 510 | 3 511 | 3 512 | 6 513 | 3 514 | 3 515 | 3 516 | 3 517 | 3 518 | 3 519 | 7 520 | 3 521 | 3 522 | 3 523 | 6 524 | 3 525 | 3 526 | 3 527 | 3 528 | 3 529 | 3 530 | 3 531 | 3 532 | 3 533 | 1 534 | 3 535 | 3 536 | 3 537 | 3 538 | 3 539 | 3 540 | 3 541 | 6 542 | 6 543 | 3 544 | 3 545 | 3 546 | 3 547 | 3 548 | 3 549 | 3 550 | 3 551 | 3 552 | 6 553 | 3 554 | 3 555 | 6 556 | 3 557 | 3 558 | 3 559 | 3 560 | 3 561 | 3 562 | 3 563 | 6 564 | 6 565 | 3 566 | 3 567 | 3 568 | 3 569 | 3 570 | 3 571 | 3 572 | 3 573 | 3 574 | 7 575 | 6 576 | 5 577 | 3 578 | 6 579 | 3 580 | 3 581 | 3 582 | 7 583 | 3 584 | 3 585 | 3 586 | 6 587 | 6 588 | 1 589 | 3 590 | 3 591 | 3 592 | 3 593 | 7 594 | 3 595 | 7 596 | 3 597 | 6 598 | 3 599 | 3 600 | 3 601 | 6 602 | 7 603 | 7 604 | 7 605 | 6 606 | 3 607 | 3 608 | 6 609 | 6 610 | 3 611 | 3 612 | 7 613 | 7 614 | 7 615 | 7 616 | 7 617 | 7 618 | 6 619 | 6 620 | 3 621 | 3 622 | 3 623 | 3 624 | 6 625 | 7 626 | 7 627 | 3 628 | 7 629 | 7 630 | 7 631 | 3 632 | 6 633 | 6 634 | 3 635 | 3 636 | 6 637 | 3 638 | 3 639 | 3 640 | 7 641 | 3 642 | 3 643 | 7 644 | 7 645 | 3 646 | 3 647 | 6 648 | 6 649 | 6 650 | 6 651 | 3 652 | 3 653 | 3 654 | 7 655 | 7 656 | 6 657 | 7 658 | 3 659 | 3 660 | 3 661 | 6 662 | 6 663 | 3 664 | 3 665 | 3 666 | 7 667 | 3 668 | 6 669 | 3 670 | 3 671 | 3 672 | 3 673 | 3 674 | 3 675 | 6 676 | 6 677 | 6 678 | 7 679 | 3 680 | 7 681 | 7 682 | 7 683 | 3 684 | 3 685 | 3 686 | 6 687 | 6 688 | 6 689 | 3 690 | 7 691 | 3 692 | 3 693 | 3 694 | 3 695 | 3 696 | 3 697 | 3 698 | 3 699 | 6 700 | 6 701 | 6 702 | 7 703 | 3 704 | 3 705 | 3 706 | 3 707 | 3 708 | 3 709 | 3 710 | 3 711 | 6 712 | 6 713 | 6 714 | 7 715 | 3 716 | 3 717 | 3 718 | 3 719 | 3 720 | 3 721 | 3 722 | 3 723 | 3 724 | 6 725 | 6 726 | 3 727 | 3 728 | 3 729 | 3 730 | 6 731 | 3 732 | 3 733 | 3 734 | 3 735 | 3 736 | 3 737 | 3 738 | 3 739 | 3 740 | 3 741 | 3 742 | 3 743 | 3 744 | 3 745 | 3 746 | 3 747 | 5 748 | 3 749 | 3 750 | 3 751 | 3 752 | 3 753 | 3 754 | 3 755 | 3 756 | 3 757 | 3 758 | 3 759 | 7 760 | 3 761 | 3 762 | 3 763 | 3 764 | 3 765 | 3 766 | 3 767 | 7 768 | 7 769 | 3 770 | 3 771 | 3 772 | 3 773 | 3 774 | 3 775 | 3 776 | 3 777 | 7 778 | 7 779 | 3 780 | 3 781 | 6 782 | 3 783 | 3 784 | 3 785 | 3 786 | 3 787 | 5 788 | 3 789 | 3 790 | 3 791 | 3 792 | 7 793 | 3 794 | 3 795 | 3 796 | 3 797 | 3 798 | 7 799 | 7 800 | 3 801 | 3 802 | 3 803 | 3 804 | 3 805 | 3 806 | 3 807 | 3 808 | 3 809 | 3 810 | 7 811 | 3 812 | 3 813 | 3 814 | 3 815 | 3 816 | 3 817 | 3 818 | 3 819 | 3 820 | 3 821 | 3 822 | 3 823 | 3 824 | 3 825 | 3 826 | 3 827 | 3 828 | 3 829 | 3 830 | 3 831 | 3 832 | 3 833 | 3 834 | 3 835 | 3 836 | 3 837 | 3 838 | 3 839 | 3 840 | 3 841 | 3 842 | 3 843 | 6 844 | 6 845 | 3 846 | 3 847 | 3 848 | 3 849 | 3 850 | 3 851 | 3 852 | 3 853 | 3 854 | 6 855 | 6 856 | 3 857 | 3 858 | 3 859 | 3 860 | 3 861 | 3 862 | 3 863 | 3 864 | 6 865 | 3 866 | 3 867 | 3 868 | 3 869 | 3 870 | 3 871 | 3 872 | 3 873 | 3 874 | 3 875 | 3 876 | 6 877 | 3 878 | 3 879 | 3 880 | 3 881 | 3 882 | 3 883 | 3 884 | 3 885 | 3 886 | 6 887 | 6 888 | 3 889 | 3 890 | 3 891 | 3 892 | 3 893 | 3 894 | 3 895 | 3 896 | 3 897 | 6 898 | 6 899 | 3 900 | 3 901 | 3 902 | 3 903 | 3 904 | 3 905 | 3 906 | 3 907 | 6 908 | 3 909 | 3 910 | 3 911 | 3 912 | 3 913 | 3 914 | 7 915 | 3 916 | 3 917 | 6 918 | 3 919 | 3 920 | 3 921 | 3 922 | 3 923 | 3 924 | 3 925 | 3 926 | 3 927 | 3 928 | 3 929 | 3 930 | 3 931 | 3 932 | 3 933 | 3 934 | 3 935 | 3 936 | 6 937 | 3 938 | 3 939 | 3 940 | 3 941 | 3 942 | 7 943 | 3 944 | 3 945 | 3 946 | 3 947 | 3 948 | 3 949 | 6 950 | 3 951 | 3 952 | 3 953 | 7 954 | 3 955 | 3 956 | 6 957 | 3 958 | 3 959 | 3 960 | 3 961 | 3 962 | 3 963 | 3 964 | 3 965 | 6 966 | 6 967 | 3 968 | 6 969 | 6 970 | 3 971 | 3 972 | 3 973 | 3 974 | 3 975 | 3 976 | 6 977 | 6 978 | 6 979 | 6 980 | 6 981 | 3 982 | 3 983 | 3 984 | 3 985 | 3 986 | 6 987 | 6 988 | 6 989 | 6 990 | 6 991 | 6 992 | 3 993 | 3 994 | 3 995 | 3 996 | 3 997 | 6 998 | 6 999 | 6 1000 | 6 1001 | 6 1002 | 6 1003 | 6 1004 | 3 1005 | 3 1006 | 3 1007 | 6 1008 | 6 1009 | 7 1010 | 6 1011 | 6 1012 | 6 1013 | 6 1014 | 3 1015 | 3 1016 | 3 1017 | 3 1018 | 6 1019 | 6 1020 | 3 1021 | 6 1022 | 6 1023 | 6 1024 | 6 1025 | 6 1026 | 6 1027 | 3 1028 | 3 1029 | 5 1030 | 6 1031 | 6 1032 | 3 1033 | 3 1034 | 3 1035 | 3 1036 | 6 1037 | 6 1038 | 3 1039 | 3 1040 | 3 1041 | 3 1042 | 3 1043 | 6 1044 | 3 1045 | 3 1046 | 6 1047 | 6 1048 | 3 1049 | 3 1050 | 3 1051 | 3 1052 | 3 1053 | 6 1054 | 6 1055 | 3 1056 | 3 1057 | 4 1058 | 6 1059 | 3 1060 | 3 1061 | 3 1062 | 3 1063 | 3 1064 | 6 1065 | 3 1066 | 3 1067 | 3 1068 | 6 1069 | 3 1070 | 3 1071 | 3 1072 | 3 1073 | 3 1074 | 6 1075 | 6 1076 | 6 1077 | 3 1078 | 7 1079 | 3 1080 | 6 1081 | 6 1082 | 3 1083 | 3 1084 | 3 1085 | 3 1086 | 3 1087 | 6 1088 | 3 1089 | 3 1090 | 3 1091 | 6 1092 | 6 1093 | 6 1094 | 3 1095 | 3 1096 | 3 1097 | 3 1098 | 6 1099 | 6 1100 | 6 1101 | 3 1102 | 3 1103 | 6 1104 | 6 1105 | 6 1106 | 3 1107 | 3 1108 | 3 1109 | 3 1110 | 6 1111 | 6 1112 | 3 1113 | 3 1114 | 3 1115 | 6 1116 | 6 1117 | 3 1118 | 3 1119 | 3 1120 | 3 1121 | 3 1122 | 3 1123 | 6 1124 | 6 1125 | 3 1126 | 4 1127 | 6 1128 | 6 1129 | 3 1130 | 3 1131 | 3 1132 | 3 1133 | 3 1134 | 3 1135 | 6 1136 | 6 1137 | 7 1138 | 6 1139 | 6 1140 | 6 1141 | 3 1142 | 3 1143 | 3 1144 | 3 1145 | 3 1146 | 6 1147 | 6 1148 | 7 1149 | 3 1150 | 6 1151 | 6 1152 | 3 1153 | 3 1154 | 3 1155 | 3 1156 | 7 1157 | 3 1158 | 6 1159 | 6 1160 | 3 1161 | 6 1162 | 6 1163 | 6 1164 | 3 1165 | 7 1166 | 3 1167 | 3 1168 | 6 1169 | 6 1170 | 1 1171 | 3 1172 | 6 1173 | 3 1174 | 3 1175 | 3 1176 | 3 1177 | 1 1178 | 6 1179 | 6 1180 | 6 1181 | 6 1182 | 3 1183 | 3 1184 | 3 1185 | 3 1186 | 3 1187 | 3 1188 | 7 1189 | 3 1190 | 6 1191 | 5 1192 | 6 1193 | 6 1194 | 3 1195 | 3 1196 | 3 1197 | 3 1198 | 3 1199 | 3 1200 | 3 1201 | 6 1202 | 6 1203 | 6 1204 | 6 1205 | 3 1206 | 3 1207 | 3 1208 | 3 1209 | 3 1210 | 3 1211 | 7 1212 | 3 1213 | 6 1214 | 6 1215 | 6 1216 | 3 1217 | 3 1218 | 3 1219 | 3 1220 | 3 1221 | 7 1222 | 3 1223 | 7 1224 | 6 1225 | 6 1226 | 3 1227 | 3 1228 | 3 1229 | 3 1230 | 3 1231 | 3 1232 | 7 1233 | 6 1234 | 3 1235 | 3 1236 | 3 1237 | 7 1238 | 3 1239 | 3 1240 | 3 1241 | 3 1242 | 3 1243 | 3 1244 | -------------------------------------------------------------------------------- /models/SYM/genom.csv: -------------------------------------------------------------------------------- 1 | genom 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 7 | 6 8 | 7 9 | 3 10 | 2 11 | 3 12 | 3 13 | 3 14 | 3 15 | 3 16 | 3 17 | 3 18 | 3 19 | 3 20 | 3 21 | 3 22 | 3 23 | 3 24 | 3 25 | 3 26 | 3 27 | 3 28 | 3 29 | 3 30 | 3 31 | 3 32 | 3 33 | 3 34 | 3 35 | 3 36 | 3 37 | 3 38 | 3 39 | 3 40 | 3 41 | 3 42 | 3 43 | 3 44 | 3 45 | 3 46 | 7 47 | 3 48 | 3 49 | 3 50 | 3 51 | 3 52 | 3 53 | 3 54 | 3 55 | 2 56 | 3 57 | 6 58 | 3 59 | 3 60 | 3 61 | 3 62 | 3 63 | 3 64 | 3 65 | 3 66 | 3 67 | 3 68 | 3 69 | 3 70 | 3 71 | 3 72 | 3 73 | 3 74 | 3 75 | 3 76 | 3 77 | 3 78 | 3 79 | 3 80 | 3 81 | 3 82 | 3 83 | 3 84 | 3 85 | 3 86 | 3 87 | 3 88 | 3 89 | 3 90 | 3 91 | 3 92 | 3 93 | 3 94 | 3 95 | 3 96 | 3 97 | 3 98 | 3 99 | 3 100 | 3 101 | 3 102 | 3 103 | 3 104 | 3 105 | 3 106 | 3 107 | 3 108 | 3 109 | 3 110 | 3 111 | 3 112 | 6 113 | 3 114 | 3 115 | 3 116 | 3 117 | 3 118 | 3 119 | 6 120 | 6 121 | 3 122 | 3 123 | 3 124 | 3 125 | 3 126 | 3 127 | 3 128 | 6 129 | 7 130 | 3 131 | 3 132 | 3 133 | 3 134 | 6 135 | 3 136 | 3 137 | 3 138 | 3 139 | 6 140 | 7 141 | 6 142 | 3 143 | 3 144 | 3 145 | 6 146 | 6 147 | 3 148 | 3 149 | 3 150 | 3 151 | 7 152 | 3 153 | 7 154 | 3 155 | 3 156 | 3 157 | 3 158 | 3 159 | 3 160 | 6 161 | 3 162 | 3 163 | 3 164 | 3 165 | 3 166 | 3 167 | 7 168 | 7 169 | 3 170 | 3 171 | 3 172 | 3 173 | 3 174 | 3 175 | 7 176 | 6 177 | 3 178 | 3 179 | 3 180 | 3 181 | 3 182 | 3 183 | 3 184 | 3 185 | 7 186 | 3 187 | 3 188 | 3 189 | 3 190 | 3 191 | 3 192 | 3 193 | 3 194 | 3 195 | 3 196 | 3 197 | 3 198 | 3 199 | 3 200 | 3 201 | 6 202 | 6 203 | 3 204 | 3 205 | 3 206 | 3 207 | 3 208 | 3 209 | 3 210 | 3 211 | 7 212 | 6 213 | 3 214 | 3 215 | 3 216 | 3 217 | 3 218 | 3 219 | 3 220 | 3 221 | 7 222 | 3 223 | 3 224 | 3 225 | 3 226 | 3 227 | 3 228 | 3 229 | 3 230 | 3 231 | 3 232 | 3 233 | 3 234 | 3 235 | 3 236 | 3 237 | 3 238 | 3 239 | 3 240 | 3 241 | 7 242 | 3 243 | 3 244 | 3 245 | 3 246 | 3 247 | 3 248 | 3 249 | 3 250 | 3 251 | 3 252 | 3 253 | 3 254 | 3 255 | 3 256 | 3 257 | 3 258 | 3 259 | 3 260 | 3 261 | 3 262 | 3 263 | 3 264 | 3 265 | 3 266 | 3 267 | 3 268 | 3 269 | 3 270 | 3 271 | 3 272 | 3 273 | 3 274 | 3 275 | 3 276 | 3 277 | 3 278 | 7 279 | 3 280 | 3 281 | 3 282 | 3 283 | 3 284 | 3 285 | 3 286 | 3 287 | 6 288 | 3 289 | 3 290 | 3 291 | 3 292 | 3 293 | 3 294 | 3 295 | 3 296 | 3 297 | 3 298 | 3 299 | 3 300 | 3 301 | 3 302 | 3 303 | 3 304 | 3 305 | 6 306 | 3 307 | 3 308 | 3 309 | 3 310 | 3 311 | 3 312 | 3 313 | 3 314 | 3 315 | 6 316 | 3 317 | 3 318 | 3 319 | 3 320 | 3 321 | 3 322 | 3 323 | 3 324 | 3 325 | 6 326 | 3 327 | 3 328 | 3 329 | 3 330 | 3 331 | 3 332 | 3 333 | 3 334 | 3 335 | 3 336 | 3 337 | 7 338 | 3 339 | 3 340 | 3 341 | 3 342 | 3 343 | 3 344 | 3 345 | 3 346 | 3 347 | 3 348 | 3 349 | 3 350 | 3 351 | 3 352 | 3 353 | 3 354 | 3 355 | 3 356 | 3 357 | 3 358 | 3 359 | 7 360 | 3 361 | 3 362 | 3 363 | 3 364 | 3 365 | 3 366 | 3 367 | 3 368 | 3 369 | 3 370 | 6 371 | 3 372 | 3 373 | 3 374 | 3 375 | 3 376 | 3 377 | 3 378 | 3 379 | 3 380 | 3 381 | 5 382 | 3 383 | 3 384 | 6 385 | 3 386 | 3 387 | 3 388 | 3 389 | 3 390 | 3 391 | 3 392 | 3 393 | 3 394 | 3 395 | 3 396 | 6 397 | 3 398 | 3 399 | 3 400 | 3 401 | 3 402 | 3 403 | 3 404 | 3 405 | 3 406 | 3 407 | 3 408 | 6 409 | 3 410 | 3 411 | 3 412 | 3 413 | 1 414 | 3 415 | 3 416 | 3 417 | 3 418 | 3 419 | 3 420 | 3 421 | 7 422 | 3 423 | 3 424 | 7 425 | 3 426 | 3 427 | 3 428 | 3 429 | 3 430 | 3 431 | 3 432 | 3 433 | 3 434 | 3 435 | 3 436 | 3 437 | 3 438 | 7 439 | 3 440 | 3 441 | 3 442 | 3 443 | 3 444 | 3 445 | 3 446 | 3 447 | 3 448 | 3 449 | 3 450 | 3 451 | 3 452 | 3 453 | 3 454 | 3 455 | 3 456 | 3 457 | 3 458 | 3 459 | 3 460 | 3 461 | 3 462 | 3 463 | 3 464 | 3 465 | 3 466 | 7 467 | 3 468 | 3 469 | 3 470 | 3 471 | 3 472 | 3 473 | 3 474 | 3 475 | 3 476 | 3 477 | 3 478 | 3 479 | 3 480 | 3 481 | 3 482 | 3 483 | 3 484 | 3 485 | 3 486 | 3 487 | 3 488 | 3 489 | 3 490 | 3 491 | 3 492 | 3 493 | 3 494 | 3 495 | 3 496 | 3 497 | 7 498 | 3 499 | 3 500 | 3 501 | 3 502 | 3 503 | 3 504 | 3 505 | 3 506 | 3 507 | 3 508 | 7 509 | 3 510 | 3 511 | 3 512 | 6 513 | 3 514 | 3 515 | 3 516 | 3 517 | 3 518 | 3 519 | 7 520 | 3 521 | 3 522 | 3 523 | 6 524 | 3 525 | 3 526 | 3 527 | 3 528 | 3 529 | 3 530 | 3 531 | 3 532 | 3 533 | 1 534 | 3 535 | 3 536 | 3 537 | 3 538 | 3 539 | 3 540 | 3 541 | 6 542 | 6 543 | 3 544 | 3 545 | 3 546 | 3 547 | 3 548 | 3 549 | 3 550 | 3 551 | 3 552 | 6 553 | 3 554 | 3 555 | 6 556 | 3 557 | 3 558 | 3 559 | 3 560 | 3 561 | 3 562 | 3 563 | 6 564 | 6 565 | 3 566 | 3 567 | 3 568 | 3 569 | 3 570 | 3 571 | 3 572 | 3 573 | 3 574 | 7 575 | 6 576 | 5 577 | 3 578 | 6 579 | 3 580 | 3 581 | 3 582 | 7 583 | 3 584 | 3 585 | 3 586 | 6 587 | 6 588 | 1 589 | 3 590 | 3 591 | 3 592 | 3 593 | 7 594 | 3 595 | 7 596 | 3 597 | 6 598 | 3 599 | 3 600 | 3 601 | 6 602 | 7 603 | 7 604 | 7 605 | 6 606 | 3 607 | 3 608 | 6 609 | 6 610 | 3 611 | 3 612 | 7 613 | 7 614 | 7 615 | 7 616 | 7 617 | 7 618 | 6 619 | 6 620 | 3 621 | 3 622 | 3 623 | 3 624 | 6 625 | 7 626 | 7 627 | 3 628 | 7 629 | 7 630 | 7 631 | 3 632 | 6 633 | 6 634 | 3 635 | 3 636 | 6 637 | 3 638 | 3 639 | 3 640 | 7 641 | 3 642 | 3 643 | 7 644 | 7 645 | 3 646 | 3 647 | 6 648 | 6 649 | 6 650 | 6 651 | 3 652 | 3 653 | 3 654 | 7 655 | 7 656 | 6 657 | 7 658 | 3 659 | 3 660 | 3 661 | 6 662 | 6 663 | 3 664 | 3 665 | 3 666 | 7 667 | 3 668 | 6 669 | 3 670 | 3 671 | 3 672 | 3 673 | 3 674 | 3 675 | 6 676 | 6 677 | 6 678 | 7 679 | 3 680 | 7 681 | 7 682 | 7 683 | 3 684 | 3 685 | 3 686 | 6 687 | 6 688 | 6 689 | 3 690 | 7 691 | 3 692 | 3 693 | 3 694 | 3 695 | 3 696 | 3 697 | 3 698 | 3 699 | 6 700 | 6 701 | 6 702 | 7 703 | 3 704 | 3 705 | 3 706 | 3 707 | 3 708 | 3 709 | 3 710 | 3 711 | 6 712 | 6 713 | 6 714 | 7 715 | 3 716 | 3 717 | 3 718 | 3 719 | 3 720 | 3 721 | 3 722 | 3 723 | 3 724 | 6 725 | 6 726 | 3 727 | 3 728 | 3 729 | 3 730 | 6 731 | 3 732 | 3 733 | 3 734 | 3 735 | 3 736 | 3 737 | 3 738 | 3 739 | 3 740 | 3 741 | 3 742 | 3 743 | 3 744 | 3 745 | 3 746 | 3 747 | 5 748 | 3 749 | 3 750 | 3 751 | 3 752 | 3 753 | 3 754 | 3 755 | 3 756 | 3 757 | 3 758 | 3 759 | 7 760 | 3 761 | 3 762 | 3 763 | 3 764 | 3 765 | 3 766 | 3 767 | 7 768 | 7 769 | 3 770 | 3 771 | 3 772 | 3 773 | 3 774 | 3 775 | 3 776 | 3 777 | 7 778 | 7 779 | 3 780 | 3 781 | 6 782 | 3 783 | 3 784 | 3 785 | 3 786 | 3 787 | 5 788 | 3 789 | 3 790 | 3 791 | 3 792 | 7 793 | 3 794 | 3 795 | 3 796 | 3 797 | 3 798 | 7 799 | 7 800 | 3 801 | 3 802 | 3 803 | 3 804 | 3 805 | 3 806 | 3 807 | 3 808 | 3 809 | 3 810 | 7 811 | 3 812 | 3 813 | 3 814 | 3 815 | 3 816 | 3 817 | 3 818 | 3 819 | 3 820 | 3 821 | 3 822 | 3 823 | 3 824 | 3 825 | 3 826 | 3 827 | 3 828 | 3 829 | 3 830 | 3 831 | 3 832 | 3 833 | 3 834 | 3 835 | 3 836 | 3 837 | 3 838 | 3 839 | 3 840 | 3 841 | 3 842 | 3 843 | 6 844 | 6 845 | 3 846 | 3 847 | 3 848 | 3 849 | 3 850 | 3 851 | 3 852 | 3 853 | 3 854 | 6 855 | 6 856 | 3 857 | 3 858 | 3 859 | 3 860 | 3 861 | 3 862 | 3 863 | 3 864 | 6 865 | 3 866 | 3 867 | 3 868 | 3 869 | 3 870 | 3 871 | 3 872 | 3 873 | 3 874 | 3 875 | 3 876 | 6 877 | 3 878 | 3 879 | 3 880 | 3 881 | 3 882 | 3 883 | 3 884 | 3 885 | 3 886 | 6 887 | 6 888 | 3 889 | 3 890 | 3 891 | 3 892 | 3 893 | 3 894 | 3 895 | 3 896 | 3 897 | 6 898 | 6 899 | 3 900 | 3 901 | 3 902 | 3 903 | 3 904 | 3 905 | 3 906 | 3 907 | 6 908 | 3 909 | 3 910 | 3 911 | 3 912 | 3 913 | 3 914 | 7 915 | 3 916 | 3 917 | 6 918 | 3 919 | 3 920 | 3 921 | 3 922 | 3 923 | 3 924 | 3 925 | 3 926 | 3 927 | 3 928 | 3 929 | 3 930 | 3 931 | 3 932 | 3 933 | 3 934 | 3 935 | 3 936 | 6 937 | 3 938 | 3 939 | 3 940 | 3 941 | 3 942 | 7 943 | 3 944 | 3 945 | 3 946 | 3 947 | 3 948 | 3 949 | 6 950 | 3 951 | 3 952 | 3 953 | 7 954 | 3 955 | 3 956 | 6 957 | 3 958 | 3 959 | 3 960 | 3 961 | 3 962 | 3 963 | 3 964 | 3 965 | 6 966 | 6 967 | 3 968 | 6 969 | 6 970 | 3 971 | 3 972 | 3 973 | 3 974 | 3 975 | 3 976 | 6 977 | 6 978 | 6 979 | 6 980 | 6 981 | 3 982 | 3 983 | 3 984 | 3 985 | 3 986 | 6 987 | 6 988 | 6 989 | 6 990 | 6 991 | 6 992 | 3 993 | 3 994 | 3 995 | 3 996 | 3 997 | 6 998 | 6 999 | 6 1000 | 6 1001 | 6 1002 | 6 1003 | 6 1004 | 3 1005 | 3 1006 | 3 1007 | 6 1008 | 6 1009 | 7 1010 | 6 1011 | 6 1012 | 6 1013 | 6 1014 | 3 1015 | 3 1016 | 3 1017 | 3 1018 | 6 1019 | 6 1020 | 3 1021 | 6 1022 | 6 1023 | 6 1024 | 6 1025 | 6 1026 | 6 1027 | 3 1028 | 3 1029 | 5 1030 | 6 1031 | 6 1032 | 3 1033 | 3 1034 | 3 1035 | 3 1036 | 6 1037 | 6 1038 | 3 1039 | 3 1040 | 3 1041 | 3 1042 | 3 1043 | 6 1044 | 3 1045 | 3 1046 | 6 1047 | 6 1048 | 3 1049 | 3 1050 | 3 1051 | 3 1052 | 3 1053 | 6 1054 | 6 1055 | 3 1056 | 3 1057 | 4 1058 | 6 1059 | 3 1060 | 3 1061 | 3 1062 | 3 1063 | 3 1064 | 6 1065 | 3 1066 | 3 1067 | 3 1068 | 6 1069 | 3 1070 | 3 1071 | 3 1072 | 3 1073 | 3 1074 | 6 1075 | 6 1076 | 6 1077 | 3 1078 | 7 1079 | 3 1080 | 6 1081 | 6 1082 | 3 1083 | 3 1084 | 3 1085 | 3 1086 | 3 1087 | 6 1088 | 3 1089 | 3 1090 | 3 1091 | 6 1092 | 6 1093 | 6 1094 | 3 1095 | 3 1096 | 3 1097 | 3 1098 | 6 1099 | 6 1100 | 6 1101 | 3 1102 | 3 1103 | 6 1104 | 6 1105 | 6 1106 | 3 1107 | 3 1108 | 3 1109 | 3 1110 | 6 1111 | 6 1112 | 3 1113 | 3 1114 | 3 1115 | 6 1116 | 6 1117 | 3 1118 | 3 1119 | 3 1120 | 3 1121 | 3 1122 | 3 1123 | 6 1124 | 6 1125 | 3 1126 | 4 1127 | 6 1128 | 6 1129 | 3 1130 | 3 1131 | 3 1132 | 3 1133 | 3 1134 | 3 1135 | 6 1136 | 6 1137 | 7 1138 | 6 1139 | 6 1140 | 6 1141 | 3 1142 | 3 1143 | 3 1144 | 3 1145 | 3 1146 | 6 1147 | 6 1148 | 7 1149 | 3 1150 | 6 1151 | 6 1152 | 3 1153 | 3 1154 | 3 1155 | 3 1156 | 7 1157 | 3 1158 | 6 1159 | 6 1160 | 3 1161 | 6 1162 | 6 1163 | 6 1164 | 3 1165 | 7 1166 | 3 1167 | 3 1168 | 6 1169 | 6 1170 | 1 1171 | 3 1172 | 6 1173 | 3 1174 | 3 1175 | 3 1176 | 3 1177 | 1 1178 | 6 1179 | 6 1180 | 6 1181 | 6 1182 | 3 1183 | 3 1184 | 3 1185 | 3 1186 | 3 1187 | 3 1188 | 7 1189 | 3 1190 | 6 1191 | 5 1192 | 6 1193 | 6 1194 | 3 1195 | 3 1196 | 3 1197 | 3 1198 | 3 1199 | 3 1200 | 3 1201 | 6 1202 | 6 1203 | 6 1204 | 6 1205 | 3 1206 | 3 1207 | 3 1208 | 3 1209 | 3 1210 | 3 1211 | 7 1212 | 3 1213 | 6 1214 | 6 1215 | 6 1216 | 3 1217 | 3 1218 | 3 1219 | 3 1220 | 3 1221 | 7 1222 | 3 1223 | 7 1224 | 6 1225 | 6 1226 | 3 1227 | 3 1228 | 3 1229 | 3 1230 | 3 1231 | 3 1232 | 7 1233 | 6 1234 | 3 1235 | 3 1236 | 3 1237 | 7 1238 | 3 1239 | 3 1240 | 3 1241 | 3 1242 | 3 1243 | 3 1244 | -------------------------------------------------------------------------------- /models/WYLD/genom.csv: -------------------------------------------------------------------------------- 1 | genom 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 7 | 6 8 | 7 9 | 3 10 | 2 11 | 3 12 | 3 13 | 3 14 | 3 15 | 3 16 | 3 17 | 3 18 | 3 19 | 3 20 | 3 21 | 3 22 | 3 23 | 3 24 | 3 25 | 3 26 | 3 27 | 3 28 | 3 29 | 3 30 | 3 31 | 3 32 | 3 33 | 3 34 | 3 35 | 3 36 | 3 37 | 3 38 | 3 39 | 3 40 | 3 41 | 3 42 | 3 43 | 3 44 | 3 45 | 3 46 | 7 47 | 3 48 | 3 49 | 3 50 | 3 51 | 3 52 | 3 53 | 3 54 | 3 55 | 2 56 | 3 57 | 6 58 | 3 59 | 3 60 | 3 61 | 3 62 | 3 63 | 3 64 | 3 65 | 3 66 | 3 67 | 3 68 | 3 69 | 3 70 | 3 71 | 3 72 | 3 73 | 3 74 | 3 75 | 3 76 | 3 77 | 3 78 | 3 79 | 3 80 | 3 81 | 3 82 | 3 83 | 3 84 | 3 85 | 3 86 | 3 87 | 3 88 | 3 89 | 3 90 | 3 91 | 3 92 | 3 93 | 3 94 | 3 95 | 3 96 | 3 97 | 3 98 | 3 99 | 3 100 | 3 101 | 3 102 | 3 103 | 3 104 | 3 105 | 3 106 | 3 107 | 3 108 | 3 109 | 3 110 | 3 111 | 3 112 | 6 113 | 3 114 | 3 115 | 3 116 | 3 117 | 3 118 | 3 119 | 6 120 | 6 121 | 3 122 | 3 123 | 3 124 | 3 125 | 3 126 | 3 127 | 3 128 | 6 129 | 7 130 | 3 131 | 3 132 | 3 133 | 3 134 | 6 135 | 3 136 | 3 137 | 3 138 | 3 139 | 6 140 | 7 141 | 6 142 | 3 143 | 3 144 | 3 145 | 6 146 | 6 147 | 3 148 | 3 149 | 3 150 | 3 151 | 7 152 | 3 153 | 7 154 | 3 155 | 3 156 | 3 157 | 3 158 | 3 159 | 3 160 | 6 161 | 3 162 | 3 163 | 3 164 | 3 165 | 3 166 | 3 167 | 7 168 | 7 169 | 3 170 | 3 171 | 3 172 | 3 173 | 3 174 | 3 175 | 7 176 | 6 177 | 3 178 | 3 179 | 3 180 | 3 181 | 3 182 | 3 183 | 3 184 | 3 185 | 7 186 | 3 187 | 3 188 | 3 189 | 3 190 | 3 191 | 3 192 | 3 193 | 3 194 | 3 195 | 3 196 | 3 197 | 3 198 | 3 199 | 3 200 | 3 201 | 6 202 | 6 203 | 3 204 | 3 205 | 3 206 | 3 207 | 3 208 | 3 209 | 3 210 | 3 211 | 7 212 | 6 213 | 3 214 | 3 215 | 3 216 | 3 217 | 3 218 | 3 219 | 3 220 | 3 221 | 7 222 | 3 223 | 3 224 | 3 225 | 3 226 | 3 227 | 3 228 | 3 229 | 3 230 | 3 231 | 3 232 | 3 233 | 3 234 | 3 235 | 3 236 | 3 237 | 3 238 | 3 239 | 3 240 | 3 241 | 7 242 | 3 243 | 3 244 | 3 245 | 3 246 | 3 247 | 3 248 | 3 249 | 3 250 | 3 251 | 3 252 | 3 253 | 3 254 | 3 255 | 3 256 | 3 257 | 3 258 | 3 259 | 3 260 | 3 261 | 3 262 | 3 263 | 3 264 | 3 265 | 3 266 | 3 267 | 3 268 | 3 269 | 3 270 | 3 271 | 3 272 | 3 273 | 3 274 | 3 275 | 3 276 | 3 277 | 3 278 | 7 279 | 3 280 | 3 281 | 3 282 | 3 283 | 3 284 | 3 285 | 3 286 | 3 287 | 6 288 | 3 289 | 3 290 | 3 291 | 3 292 | 3 293 | 3 294 | 3 295 | 3 296 | 3 297 | 3 298 | 3 299 | 3 300 | 3 301 | 3 302 | 3 303 | 3 304 | 3 305 | 6 306 | 3 307 | 3 308 | 3 309 | 3 310 | 3 311 | 3 312 | 3 313 | 3 314 | 3 315 | 6 316 | 3 317 | 3 318 | 3 319 | 3 320 | 3 321 | 3 322 | 3 323 | 3 324 | 3 325 | 6 326 | 3 327 | 3 328 | 3 329 | 3 330 | 3 331 | 3 332 | 3 333 | 3 334 | 3 335 | 3 336 | 3 337 | 7 338 | 3 339 | 3 340 | 3 341 | 3 342 | 3 343 | 3 344 | 3 345 | 3 346 | 3 347 | 3 348 | 3 349 | 3 350 | 3 351 | 3 352 | 3 353 | 3 354 | 3 355 | 3 356 | 3 357 | 3 358 | 3 359 | 7 360 | 3 361 | 3 362 | 3 363 | 3 364 | 3 365 | 3 366 | 3 367 | 3 368 | 3 369 | 3 370 | 6 371 | 3 372 | 3 373 | 3 374 | 3 375 | 3 376 | 3 377 | 3 378 | 3 379 | 3 380 | 3 381 | 5 382 | 3 383 | 3 384 | 6 385 | 3 386 | 3 387 | 3 388 | 3 389 | 3 390 | 3 391 | 3 392 | 3 393 | 3 394 | 3 395 | 3 396 | 6 397 | 3 398 | 3 399 | 3 400 | 3 401 | 3 402 | 3 403 | 3 404 | 3 405 | 3 406 | 3 407 | 3 408 | 6 409 | 3 410 | 3 411 | 3 412 | 3 413 | 1 414 | 3 415 | 3 416 | 3 417 | 3 418 | 3 419 | 3 420 | 3 421 | 7 422 | 3 423 | 3 424 | 7 425 | 3 426 | 3 427 | 3 428 | 3 429 | 3 430 | 3 431 | 3 432 | 3 433 | 3 434 | 3 435 | 3 436 | 3 437 | 3 438 | 7 439 | 3 440 | 3 441 | 3 442 | 3 443 | 3 444 | 3 445 | 3 446 | 3 447 | 3 448 | 3 449 | 3 450 | 3 451 | 3 452 | 3 453 | 3 454 | 3 455 | 3 456 | 3 457 | 3 458 | 3 459 | 3 460 | 3 461 | 3 462 | 3 463 | 3 464 | 3 465 | 3 466 | 7 467 | 3 468 | 3 469 | 3 470 | 3 471 | 3 472 | 3 473 | 3 474 | 3 475 | 3 476 | 3 477 | 3 478 | 3 479 | 3 480 | 3 481 | 3 482 | 3 483 | 3 484 | 3 485 | 3 486 | 3 487 | 3 488 | 3 489 | 3 490 | 3 491 | 3 492 | 3 493 | 3 494 | 3 495 | 3 496 | 3 497 | 7 498 | 3 499 | 3 500 | 3 501 | 3 502 | 3 503 | 3 504 | 3 505 | 3 506 | 3 507 | 3 508 | 7 509 | 3 510 | 3 511 | 3 512 | 6 513 | 3 514 | 3 515 | 3 516 | 3 517 | 3 518 | 3 519 | 7 520 | 3 521 | 3 522 | 3 523 | 6 524 | 3 525 | 3 526 | 3 527 | 3 528 | 3 529 | 3 530 | 3 531 | 3 532 | 3 533 | 1 534 | 3 535 | 3 536 | 3 537 | 3 538 | 3 539 | 3 540 | 3 541 | 6 542 | 6 543 | 3 544 | 3 545 | 3 546 | 3 547 | 3 548 | 3 549 | 3 550 | 3 551 | 3 552 | 6 553 | 3 554 | 3 555 | 6 556 | 3 557 | 3 558 | 3 559 | 3 560 | 3 561 | 3 562 | 3 563 | 6 564 | 6 565 | 3 566 | 3 567 | 3 568 | 3 569 | 3 570 | 3 571 | 3 572 | 3 573 | 3 574 | 7 575 | 6 576 | 5 577 | 3 578 | 6 579 | 3 580 | 3 581 | 3 582 | 7 583 | 3 584 | 3 585 | 3 586 | 6 587 | 6 588 | 1 589 | 3 590 | 3 591 | 3 592 | 3 593 | 7 594 | 3 595 | 7 596 | 3 597 | 6 598 | 3 599 | 3 600 | 3 601 | 6 602 | 7 603 | 7 604 | 7 605 | 6 606 | 3 607 | 3 608 | 6 609 | 6 610 | 3 611 | 3 612 | 7 613 | 7 614 | 7 615 | 7 616 | 7 617 | 7 618 | 6 619 | 6 620 | 3 621 | 3 622 | 3 623 | 3 624 | 6 625 | 7 626 | 7 627 | 3 628 | 7 629 | 7 630 | 7 631 | 3 632 | 6 633 | 6 634 | 3 635 | 3 636 | 6 637 | 3 638 | 3 639 | 3 640 | 7 641 | 3 642 | 3 643 | 7 644 | 7 645 | 3 646 | 3 647 | 6 648 | 6 649 | 6 650 | 6 651 | 3 652 | 3 653 | 3 654 | 7 655 | 7 656 | 6 657 | 7 658 | 3 659 | 3 660 | 3 661 | 6 662 | 6 663 | 3 664 | 3 665 | 3 666 | 7 667 | 3 668 | 6 669 | 3 670 | 3 671 | 3 672 | 3 673 | 3 674 | 3 675 | 6 676 | 6 677 | 6 678 | 7 679 | 3 680 | 7 681 | 7 682 | 7 683 | 3 684 | 3 685 | 3 686 | 6 687 | 6 688 | 6 689 | 3 690 | 7 691 | 3 692 | 3 693 | 3 694 | 3 695 | 3 696 | 3 697 | 3 698 | 3 699 | 6 700 | 6 701 | 6 702 | 7 703 | 3 704 | 3 705 | 3 706 | 3 707 | 3 708 | 3 709 | 3 710 | 3 711 | 6 712 | 6 713 | 6 714 | 7 715 | 3 716 | 3 717 | 3 718 | 3 719 | 3 720 | 3 721 | 3 722 | 3 723 | 3 724 | 6 725 | 6 726 | 3 727 | 3 728 | 3 729 | 3 730 | 6 731 | 3 732 | 3 733 | 3 734 | 3 735 | 3 736 | 3 737 | 3 738 | 3 739 | 3 740 | 3 741 | 3 742 | 3 743 | 3 744 | 3 745 | 3 746 | 3 747 | 5 748 | 3 749 | 3 750 | 3 751 | 3 752 | 3 753 | 3 754 | 3 755 | 3 756 | 3 757 | 3 758 | 3 759 | 7 760 | 3 761 | 3 762 | 3 763 | 3 764 | 3 765 | 3 766 | 3 767 | 7 768 | 7 769 | 3 770 | 3 771 | 3 772 | 3 773 | 3 774 | 3 775 | 3 776 | 3 777 | 7 778 | 7 779 | 3 780 | 3 781 | 6 782 | 3 783 | 3 784 | 3 785 | 3 786 | 3 787 | 5 788 | 3 789 | 3 790 | 3 791 | 3 792 | 7 793 | 3 794 | 3 795 | 3 796 | 3 797 | 3 798 | 7 799 | 7 800 | 3 801 | 3 802 | 3 803 | 3 804 | 3 805 | 3 806 | 3 807 | 3 808 | 3 809 | 3 810 | 7 811 | 3 812 | 3 813 | 3 814 | 3 815 | 3 816 | 3 817 | 3 818 | 3 819 | 3 820 | 3 821 | 3 822 | 3 823 | 3 824 | 3 825 | 3 826 | 3 827 | 3 828 | 3 829 | 3 830 | 3 831 | 3 832 | 3 833 | 3 834 | 3 835 | 3 836 | 3 837 | 3 838 | 3 839 | 3 840 | 3 841 | 3 842 | 3 843 | 6 844 | 6 845 | 3 846 | 3 847 | 3 848 | 3 849 | 3 850 | 3 851 | 3 852 | 3 853 | 3 854 | 6 855 | 6 856 | 3 857 | 3 858 | 3 859 | 3 860 | 3 861 | 3 862 | 3 863 | 3 864 | 6 865 | 3 866 | 3 867 | 3 868 | 3 869 | 3 870 | 3 871 | 3 872 | 3 873 | 3 874 | 3 875 | 3 876 | 6 877 | 3 878 | 3 879 | 3 880 | 3 881 | 3 882 | 3 883 | 3 884 | 3 885 | 3 886 | 6 887 | 6 888 | 3 889 | 3 890 | 3 891 | 3 892 | 3 893 | 3 894 | 3 895 | 3 896 | 3 897 | 6 898 | 6 899 | 3 900 | 3 901 | 3 902 | 3 903 | 3 904 | 3 905 | 3 906 | 3 907 | 6 908 | 3 909 | 3 910 | 3 911 | 3 912 | 3 913 | 3 914 | 7 915 | 3 916 | 3 917 | 6 918 | 3 919 | 3 920 | 3 921 | 3 922 | 3 923 | 3 924 | 3 925 | 3 926 | 3 927 | 3 928 | 3 929 | 3 930 | 3 931 | 3 932 | 3 933 | 3 934 | 3 935 | 3 936 | 6 937 | 3 938 | 3 939 | 3 940 | 3 941 | 3 942 | 7 943 | 3 944 | 3 945 | 3 946 | 3 947 | 3 948 | 3 949 | 6 950 | 3 951 | 3 952 | 3 953 | 7 954 | 3 955 | 3 956 | 6 957 | 3 958 | 3 959 | 3 960 | 3 961 | 3 962 | 3 963 | 3 964 | 3 965 | 6 966 | 6 967 | 3 968 | 6 969 | 6 970 | 3 971 | 3 972 | 3 973 | 3 974 | 3 975 | 3 976 | 6 977 | 6 978 | 6 979 | 6 980 | 6 981 | 3 982 | 3 983 | 3 984 | 3 985 | 3 986 | 6 987 | 6 988 | 6 989 | 6 990 | 6 991 | 6 992 | 3 993 | 3 994 | 3 995 | 3 996 | 3 997 | 6 998 | 6 999 | 6 1000 | 6 1001 | 6 1002 | 6 1003 | 6 1004 | 3 1005 | 3 1006 | 3 1007 | 6 1008 | 6 1009 | 7 1010 | 6 1011 | 6 1012 | 6 1013 | 6 1014 | 3 1015 | 3 1016 | 3 1017 | 3 1018 | 6 1019 | 6 1020 | 3 1021 | 6 1022 | 6 1023 | 6 1024 | 6 1025 | 6 1026 | 6 1027 | 3 1028 | 3 1029 | 5 1030 | 6 1031 | 6 1032 | 3 1033 | 3 1034 | 3 1035 | 3 1036 | 6 1037 | 6 1038 | 3 1039 | 3 1040 | 3 1041 | 3 1042 | 3 1043 | 6 1044 | 3 1045 | 3 1046 | 6 1047 | 6 1048 | 3 1049 | 3 1050 | 3 1051 | 3 1052 | 3 1053 | 6 1054 | 6 1055 | 3 1056 | 3 1057 | 4 1058 | 6 1059 | 3 1060 | 3 1061 | 3 1062 | 3 1063 | 3 1064 | 6 1065 | 3 1066 | 3 1067 | 3 1068 | 6 1069 | 3 1070 | 3 1071 | 3 1072 | 3 1073 | 3 1074 | 6 1075 | 6 1076 | 6 1077 | 3 1078 | 7 1079 | 3 1080 | 6 1081 | 6 1082 | 3 1083 | 3 1084 | 3 1085 | 3 1086 | 3 1087 | 6 1088 | 3 1089 | 3 1090 | 3 1091 | 6 1092 | 6 1093 | 6 1094 | 3 1095 | 3 1096 | 3 1097 | 3 1098 | 6 1099 | 6 1100 | 6 1101 | 3 1102 | 3 1103 | 6 1104 | 6 1105 | 6 1106 | 3 1107 | 3 1108 | 3 1109 | 3 1110 | 6 1111 | 6 1112 | 3 1113 | 3 1114 | 3 1115 | 6 1116 | 6 1117 | 3 1118 | 3 1119 | 3 1120 | 3 1121 | 3 1122 | 3 1123 | 6 1124 | 6 1125 | 3 1126 | 4 1127 | 6 1128 | 6 1129 | 3 1130 | 3 1131 | 3 1132 | 3 1133 | 3 1134 | 3 1135 | 6 1136 | 6 1137 | 7 1138 | 6 1139 | 6 1140 | 6 1141 | 3 1142 | 3 1143 | 3 1144 | 3 1145 | 3 1146 | 6 1147 | 6 1148 | 7 1149 | 3 1150 | 6 1151 | 6 1152 | 3 1153 | 3 1154 | 3 1155 | 3 1156 | 7 1157 | 3 1158 | 6 1159 | 6 1160 | 3 1161 | 6 1162 | 6 1163 | 6 1164 | 3 1165 | 7 1166 | 3 1167 | 3 1168 | 6 1169 | 6 1170 | 1 1171 | 3 1172 | 6 1173 | 3 1174 | 3 1175 | 3 1176 | 3 1177 | 1 1178 | 6 1179 | 6 1180 | 6 1181 | 6 1182 | 3 1183 | 3 1184 | 3 1185 | 3 1186 | 3 1187 | 3 1188 | 7 1189 | 3 1190 | 6 1191 | 5 1192 | 6 1193 | 6 1194 | 3 1195 | 3 1196 | 3 1197 | 3 1198 | 3 1199 | 3 1200 | 3 1201 | 6 1202 | 6 1203 | 6 1204 | 6 1205 | 3 1206 | 3 1207 | 3 1208 | 3 1209 | 3 1210 | 3 1211 | 7 1212 | 3 1213 | 6 1214 | 6 1215 | 6 1216 | 3 1217 | 3 1218 | 3 1219 | 3 1220 | 3 1221 | 7 1222 | 3 1223 | 7 1224 | 6 1225 | 6 1226 | 3 1227 | 3 1228 | 3 1229 | 3 1230 | 3 1231 | 3 1232 | 7 1233 | 6 1234 | 3 1235 | 3 1236 | 3 1237 | 7 1238 | 3 1239 | 3 1240 | 3 1241 | 3 1242 | 3 1243 | 3 1244 | -------------------------------------------------------------------------------- /models/HabStruct/genom.csv: -------------------------------------------------------------------------------- 1 | genom 2 | 1 3 | 2 4 | 3 5 | 4 6 | 5 7 | 6 8 | 7 9 | 3 10 | 2 11 | 3 12 | 3 13 | 3 14 | 3 15 | 3 16 | 3 17 | 3 18 | 3 19 | 3 20 | 3 21 | 3 22 | 3 23 | 3 24 | 3 25 | 3 26 | 3 27 | 3 28 | 3 29 | 3 30 | 3 31 | 3 32 | 3 33 | 3 34 | 3 35 | 3 36 | 3 37 | 3 38 | 3 39 | 3 40 | 3 41 | 3 42 | 3 43 | 3 44 | 3 45 | 3 46 | 7 47 | 3 48 | 3 49 | 3 50 | 3 51 | 3 52 | 3 53 | 3 54 | 3 55 | 2 56 | 3 57 | 6 58 | 3 59 | 3 60 | 3 61 | 3 62 | 3 63 | 3 64 | 3 65 | 3 66 | 3 67 | 3 68 | 3 69 | 3 70 | 3 71 | 3 72 | 3 73 | 3 74 | 3 75 | 3 76 | 3 77 | 3 78 | 3 79 | 3 80 | 3 81 | 3 82 | 3 83 | 3 84 | 3 85 | 3 86 | 3 87 | 3 88 | 3 89 | 3 90 | 3 91 | 3 92 | 3 93 | 3 94 | 3 95 | 3 96 | 3 97 | 3 98 | 3 99 | 3 100 | 3 101 | 3 102 | 3 103 | 3 104 | 3 105 | 3 106 | 3 107 | 3 108 | 3 109 | 3 110 | 3 111 | 3 112 | 6 113 | 3 114 | 3 115 | 3 116 | 3 117 | 3 118 | 3 119 | 6 120 | 6 121 | 3 122 | 3 123 | 3 124 | 3 125 | 3 126 | 3 127 | 3 128 | 6 129 | 7 130 | 3 131 | 3 132 | 3 133 | 3 134 | 6 135 | 3 136 | 3 137 | 3 138 | 3 139 | 6 140 | 7 141 | 6 142 | 3 143 | 3 144 | 3 145 | 6 146 | 6 147 | 3 148 | 3 149 | 3 150 | 3 151 | 7 152 | 3 153 | 7 154 | 3 155 | 3 156 | 3 157 | 3 158 | 3 159 | 3 160 | 6 161 | 3 162 | 3 163 | 3 164 | 3 165 | 3 166 | 3 167 | 7 168 | 7 169 | 3 170 | 3 171 | 3 172 | 3 173 | 3 174 | 3 175 | 7 176 | 6 177 | 3 178 | 3 179 | 3 180 | 3 181 | 3 182 | 3 183 | 3 184 | 3 185 | 7 186 | 3 187 | 3 188 | 3 189 | 3 190 | 3 191 | 3 192 | 3 193 | 3 194 | 3 195 | 3 196 | 3 197 | 3 198 | 3 199 | 3 200 | 3 201 | 6 202 | 6 203 | 3 204 | 3 205 | 3 206 | 3 207 | 3 208 | 3 209 | 3 210 | 3 211 | 7 212 | 6 213 | 3 214 | 3 215 | 3 216 | 3 217 | 3 218 | 3 219 | 3 220 | 3 221 | 7 222 | 3 223 | 3 224 | 3 225 | 3 226 | 3 227 | 3 228 | 3 229 | 3 230 | 3 231 | 3 232 | 3 233 | 3 234 | 3 235 | 3 236 | 3 237 | 3 238 | 3 239 | 3 240 | 3 241 | 7 242 | 3 243 | 3 244 | 3 245 | 3 246 | 3 247 | 3 248 | 3 249 | 3 250 | 3 251 | 3 252 | 3 253 | 3 254 | 3 255 | 3 256 | 3 257 | 3 258 | 3 259 | 3 260 | 3 261 | 3 262 | 3 263 | 3 264 | 3 265 | 3 266 | 3 267 | 3 268 | 3 269 | 3 270 | 3 271 | 3 272 | 3 273 | 3 274 | 3 275 | 3 276 | 3 277 | 3 278 | 7 279 | 3 280 | 3 281 | 3 282 | 3 283 | 3 284 | 3 285 | 3 286 | 3 287 | 6 288 | 3 289 | 3 290 | 3 291 | 3 292 | 3 293 | 3 294 | 3 295 | 3 296 | 3 297 | 3 298 | 3 299 | 3 300 | 3 301 | 3 302 | 3 303 | 3 304 | 3 305 | 6 306 | 3 307 | 3 308 | 3 309 | 3 310 | 3 311 | 3 312 | 3 313 | 3 314 | 3 315 | 6 316 | 3 317 | 3 318 | 3 319 | 3 320 | 3 321 | 3 322 | 3 323 | 3 324 | 3 325 | 6 326 | 3 327 | 3 328 | 3 329 | 3 330 | 3 331 | 3 332 | 3 333 | 3 334 | 3 335 | 3 336 | 3 337 | 7 338 | 3 339 | 3 340 | 3 341 | 3 342 | 3 343 | 3 344 | 3 345 | 3 346 | 3 347 | 3 348 | 3 349 | 3 350 | 3 351 | 3 352 | 3 353 | 3 354 | 3 355 | 3 356 | 3 357 | 3 358 | 3 359 | 7 360 | 3 361 | 3 362 | 3 363 | 3 364 | 3 365 | 3 366 | 3 367 | 3 368 | 3 369 | 3 370 | 6 371 | 3 372 | 3 373 | 3 374 | 3 375 | 3 376 | 3 377 | 3 378 | 3 379 | 3 380 | 3 381 | 5 382 | 3 383 | 3 384 | 6 385 | 3 386 | 3 387 | 3 388 | 3 389 | 3 390 | 3 391 | 3 392 | 3 393 | 3 394 | 3 395 | 3 396 | 6 397 | 3 398 | 3 399 | 3 400 | 3 401 | 3 402 | 3 403 | 3 404 | 3 405 | 3 406 | 3 407 | 3 408 | 6 409 | 3 410 | 3 411 | 3 412 | 3 413 | 1 414 | 3 415 | 3 416 | 3 417 | 3 418 | 3 419 | 3 420 | 3 421 | 7 422 | 3 423 | 3 424 | 7 425 | 3 426 | 3 427 | 3 428 | 3 429 | 3 430 | 3 431 | 3 432 | 3 433 | 3 434 | 3 435 | 3 436 | 3 437 | 3 438 | 7 439 | 3 440 | 3 441 | 3 442 | 3 443 | 3 444 | 3 445 | 3 446 | 3 447 | 3 448 | 3 449 | 3 450 | 3 451 | 3 452 | 3 453 | 3 454 | 3 455 | 3 456 | 3 457 | 3 458 | 3 459 | 3 460 | 3 461 | 3 462 | 3 463 | 3 464 | 3 465 | 3 466 | 7 467 | 3 468 | 3 469 | 3 470 | 3 471 | 3 472 | 3 473 | 3 474 | 3 475 | 3 476 | 3 477 | 3 478 | 3 479 | 3 480 | 3 481 | 3 482 | 3 483 | 3 484 | 3 485 | 3 486 | 3 487 | 3 488 | 3 489 | 3 490 | 3 491 | 3 492 | 3 493 | 3 494 | 3 495 | 3 496 | 3 497 | 7 498 | 3 499 | 3 500 | 3 501 | 3 502 | 3 503 | 3 504 | 3 505 | 3 506 | 3 507 | 3 508 | 7 509 | 3 510 | 3 511 | 3 512 | 6 513 | 3 514 | 3 515 | 3 516 | 3 517 | 3 518 | 3 519 | 7 520 | 3 521 | 3 522 | 3 523 | 6 524 | 3 525 | 3 526 | 3 527 | 3 528 | 3 529 | 3 530 | 3 531 | 3 532 | 3 533 | 1 534 | 3 535 | 3 536 | 3 537 | 3 538 | 3 539 | 3 540 | 3 541 | 6 542 | 6 543 | 3 544 | 3 545 | 3 546 | 3 547 | 3 548 | 3 549 | 3 550 | 3 551 | 3 552 | 6 553 | 3 554 | 3 555 | 6 556 | 3 557 | 3 558 | 3 559 | 3 560 | 3 561 | 3 562 | 3 563 | 6 564 | 6 565 | 3 566 | 3 567 | 3 568 | 3 569 | 3 570 | 3 571 | 3 572 | 3 573 | 3 574 | 7 575 | 6 576 | 5 577 | 3 578 | 6 579 | 3 580 | 3 581 | 3 582 | 7 583 | 3 584 | 3 585 | 3 586 | 6 587 | 6 588 | 1 589 | 3 590 | 3 591 | 3 592 | 3 593 | 7 594 | 3 595 | 7 596 | 3 597 | 6 598 | 3 599 | 3 600 | 3 601 | 6 602 | 7 603 | 7 604 | 7 605 | 6 606 | 3 607 | 3 608 | 6 609 | 6 610 | 3 611 | 3 612 | 7 613 | 7 614 | 7 615 | 7 616 | 7 617 | 7 618 | 6 619 | 6 620 | 3 621 | 3 622 | 3 623 | 3 624 | 6 625 | 7 626 | 7 627 | 3 628 | 7 629 | 7 630 | 7 631 | 3 632 | 6 633 | 6 634 | 3 635 | 3 636 | 6 637 | 3 638 | 3 639 | 3 640 | 7 641 | 3 642 | 3 643 | 7 644 | 7 645 | 3 646 | 3 647 | 6 648 | 6 649 | 6 650 | 6 651 | 3 652 | 3 653 | 3 654 | 7 655 | 7 656 | 6 657 | 7 658 | 3 659 | 3 660 | 3 661 | 6 662 | 6 663 | 3 664 | 3 665 | 3 666 | 7 667 | 3 668 | 6 669 | 3 670 | 3 671 | 3 672 | 3 673 | 3 674 | 3 675 | 6 676 | 6 677 | 6 678 | 7 679 | 3 680 | 7 681 | 7 682 | 7 683 | 3 684 | 3 685 | 3 686 | 6 687 | 6 688 | 6 689 | 3 690 | 7 691 | 3 692 | 3 693 | 3 694 | 3 695 | 3 696 | 3 697 | 3 698 | 3 699 | 6 700 | 6 701 | 6 702 | 7 703 | 3 704 | 3 705 | 3 706 | 3 707 | 3 708 | 3 709 | 3 710 | 3 711 | 6 712 | 6 713 | 6 714 | 7 715 | 3 716 | 3 717 | 3 718 | 3 719 | 3 720 | 3 721 | 3 722 | 3 723 | 3 724 | 6 725 | 6 726 | 3 727 | 3 728 | 3 729 | 3 730 | 6 731 | 3 732 | 3 733 | 3 734 | 3 735 | 3 736 | 3 737 | 3 738 | 3 739 | 3 740 | 3 741 | 3 742 | 3 743 | 3 744 | 3 745 | 3 746 | 3 747 | 5 748 | 3 749 | 3 750 | 3 751 | 3 752 | 3 753 | 3 754 | 3 755 | 3 756 | 3 757 | 3 758 | 3 759 | 7 760 | 3 761 | 3 762 | 3 763 | 3 764 | 3 765 | 3 766 | 3 767 | 7 768 | 7 769 | 3 770 | 3 771 | 3 772 | 3 773 | 3 774 | 3 775 | 3 776 | 3 777 | 7 778 | 7 779 | 3 780 | 3 781 | 6 782 | 3 783 | 3 784 | 3 785 | 3 786 | 3 787 | 5 788 | 3 789 | 3 790 | 3 791 | 3 792 | 7 793 | 3 794 | 3 795 | 3 796 | 3 797 | 3 798 | 7 799 | 7 800 | 3 801 | 3 802 | 3 803 | 3 804 | 3 805 | 3 806 | 3 807 | 3 808 | 3 809 | 3 810 | 7 811 | 3 812 | 3 813 | 3 814 | 3 815 | 3 816 | 3 817 | 3 818 | 3 819 | 3 820 | 3 821 | 3 822 | 3 823 | 3 824 | 3 825 | 3 826 | 3 827 | 3 828 | 3 829 | 3 830 | 3 831 | 3 832 | 3 833 | 3 834 | 3 835 | 3 836 | 3 837 | 3 838 | 3 839 | 3 840 | 3 841 | 3 842 | 3 843 | 6 844 | 6 845 | 3 846 | 3 847 | 3 848 | 3 849 | 3 850 | 3 851 | 3 852 | 3 853 | 3 854 | 6 855 | 6 856 | 3 857 | 3 858 | 3 859 | 3 860 | 3 861 | 3 862 | 3 863 | 3 864 | 6 865 | 3 866 | 3 867 | 3 868 | 3 869 | 3 870 | 3 871 | 3 872 | 3 873 | 3 874 | 3 875 | 3 876 | 6 877 | 3 878 | 3 879 | 3 880 | 3 881 | 3 882 | 3 883 | 3 884 | 3 885 | 3 886 | 6 887 | 6 888 | 3 889 | 3 890 | 3 891 | 3 892 | 3 893 | 3 894 | 3 895 | 3 896 | 3 897 | 6 898 | 6 899 | 3 900 | 3 901 | 3 902 | 3 903 | 3 904 | 3 905 | 3 906 | 3 907 | 6 908 | 3 909 | 3 910 | 3 911 | 3 912 | 3 913 | 3 914 | 7 915 | 3 916 | 3 917 | 6 918 | 3 919 | 3 920 | 3 921 | 3 922 | 3 923 | 3 924 | 3 925 | 3 926 | 3 927 | 3 928 | 3 929 | 3 930 | 3 931 | 3 932 | 3 933 | 3 934 | 3 935 | 3 936 | 6 937 | 3 938 | 3 939 | 3 940 | 3 941 | 3 942 | 7 943 | 3 944 | 3 945 | 3 946 | 3 947 | 3 948 | 3 949 | 6 950 | 3 951 | 3 952 | 3 953 | 7 954 | 3 955 | 3 956 | 6 957 | 3 958 | 3 959 | 3 960 | 3 961 | 3 962 | 3 963 | 3 964 | 3 965 | 6 966 | 6 967 | 3 968 | 6 969 | 6 970 | 3 971 | 3 972 | 3 973 | 3 974 | 3 975 | 3 976 | 6 977 | 6 978 | 6 979 | 6 980 | 6 981 | 3 982 | 3 983 | 3 984 | 3 985 | 3 986 | 6 987 | 6 988 | 6 989 | 6 990 | 6 991 | 6 992 | 3 993 | 3 994 | 3 995 | 3 996 | 3 997 | 6 998 | 6 999 | 6 1000 | 6 1001 | 6 1002 | 6 1003 | 6 1004 | 3 1005 | 3 1006 | 3 1007 | 6 1008 | 6 1009 | 7 1010 | 6 1011 | 6 1012 | 6 1013 | 6 1014 | 3 1015 | 3 1016 | 3 1017 | 3 1018 | 6 1019 | 6 1020 | 3 1021 | 6 1022 | 6 1023 | 6 1024 | 6 1025 | 6 1026 | 6 1027 | 3 1028 | 3 1029 | 5 1030 | 6 1031 | 6 1032 | 3 1033 | 3 1034 | 3 1035 | 3 1036 | 6 1037 | 6 1038 | 3 1039 | 3 1040 | 3 1041 | 3 1042 | 3 1043 | 6 1044 | 3 1045 | 3 1046 | 6 1047 | 6 1048 | 3 1049 | 3 1050 | 3 1051 | 3 1052 | 3 1053 | 6 1054 | 6 1055 | 3 1056 | 3 1057 | 4 1058 | 6 1059 | 3 1060 | 3 1061 | 3 1062 | 3 1063 | 3 1064 | 6 1065 | 3 1066 | 3 1067 | 3 1068 | 6 1069 | 3 1070 | 3 1071 | 3 1072 | 3 1073 | 3 1074 | 6 1075 | 6 1076 | 6 1077 | 3 1078 | 7 1079 | 3 1080 | 6 1081 | 6 1082 | 3 1083 | 3 1084 | 3 1085 | 3 1086 | 3 1087 | 6 1088 | 3 1089 | 3 1090 | 3 1091 | 6 1092 | 6 1093 | 6 1094 | 3 1095 | 3 1096 | 3 1097 | 3 1098 | 6 1099 | 6 1100 | 6 1101 | 3 1102 | 3 1103 | 6 1104 | 6 1105 | 6 1106 | 3 1107 | 3 1108 | 3 1109 | 3 1110 | 6 1111 | 6 1112 | 3 1113 | 3 1114 | 3 1115 | 6 1116 | 6 1117 | 3 1118 | 3 1119 | 3 1120 | 3 1121 | 3 1122 | 3 1123 | 6 1124 | 6 1125 | 3 1126 | 4 1127 | 6 1128 | 6 1129 | 3 1130 | 3 1131 | 3 1132 | 3 1133 | 3 1134 | 3 1135 | 6 1136 | 6 1137 | 7 1138 | 6 1139 | 6 1140 | 6 1141 | 3 1142 | 3 1143 | 3 1144 | 3 1145 | 3 1146 | 6 1147 | 6 1148 | 7 1149 | 3 1150 | 6 1151 | 6 1152 | 3 1153 | 3 1154 | 3 1155 | 3 1156 | 7 1157 | 3 1158 | 6 1159 | 6 1160 | 3 1161 | 6 1162 | 6 1163 | 6 1164 | 3 1165 | 7 1166 | 3 1167 | 3 1168 | 6 1169 | 6 1170 | 1 1171 | 3 1172 | 6 1173 | 3 1174 | 3 1175 | 3 1176 | 3 1177 | 1 1178 | 6 1179 | 6 1180 | 6 1181 | 6 1182 | 3 1183 | 3 1184 | 3 1185 | 3 1186 | 3 1187 | 3 1188 | 7 1189 | 3 1190 | 6 1191 | 5 1192 | 6 1193 | 6 1194 | 3 1195 | 3 1196 | 3 1197 | 3 1198 | 3 1199 | 3 1200 | 3 1201 | 6 1202 | 6 1203 | 6 1204 | 6 1205 | 3 1206 | 3 1207 | 3 1208 | 3 1209 | 3 1210 | 3 1211 | 7 1212 | 3 1213 | 6 1214 | 6 1215 | 6 1216 | 3 1217 | 3 1218 | 3 1219 | 3 1220 | 3 1221 | 7 1222 | 3 1223 | 7 1224 | 6 1225 | 6 1226 | 3 1227 | 3 1228 | 3 1229 | 3 1230 | 3 1231 | 3 1232 | 7 1233 | 6 1234 | 3 1235 | 3 1236 | 3 1237 | 7 1238 | 3 1239 | 3 1240 | 3 1241 | 3 1242 | 3 1243 | 3 1244 | -------------------------------------------------------------------------------- /inspyred/ec/selectors.py: -------------------------------------------------------------------------------- 1 | """ 2 | ============================================ 3 | :mod:`selectors` -- Parent selection methods 4 | ============================================ 5 | 6 | This module provides pre-defined selectors for evolutionary computations. 7 | 8 | All selector functions have the following arguments: 9 | 10 | - *random* -- the random number generator object 11 | - *population* -- the population of individuals 12 | - *args* -- a dictionary of keyword arguments 13 | 14 | Each selector function returns the list of selected individuals. 15 | 16 | .. note:: 17 | 18 | The *population* is really a shallow copy of the actual population of 19 | the evolutionary computation. This means that any activities like 20 | sorting will not affect the actual population. 21 | 22 | .. Copyright 2012 Inspired Intelligence Initiative 23 | 24 | .. This program is free software: you can redistribute it and/or modify 25 | it under the terms of the GNU General Public License as published by 26 | the Free Software Foundation, either version 3 of the License, or 27 | (at your option) any later version. 28 | 29 | .. This program is distributed in the hope that it will be useful, 30 | but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 32 | GNU General Public License for more details. 33 | 34 | .. You should have received a copy of the GNU General Public License 35 | along with this program. If not, see . 36 | 37 | .. module:: selectors 38 | .. moduleauthor:: Aaron Garrett 39 | """ 40 | 41 | 42 | def default_selection(random, population, args): 43 | """Return the population. 44 | 45 | This function acts as a default selection scheme for an evolutionary 46 | computation. It simply returns the entire population as having been 47 | selected. 48 | 49 | .. Arguments: 50 | random -- the random number generator object 51 | population -- the population of individuals 52 | args -- a dictionary of keyword arguments 53 | 54 | """ 55 | return population 56 | 57 | 58 | def truncation_selection(random, population, args): 59 | """Selects the best individuals from the population. 60 | 61 | This function performs truncation selection, which means that only 62 | the best individuals from the current population are selected. This 63 | is a completely deterministic selection mechanism. 64 | 65 | .. Arguments: 66 | random -- the random number generator object 67 | population -- the population of individuals 68 | args -- a dictionary of keyword arguments 69 | 70 | Optional keyword arguments in args: 71 | 72 | - *num_selected* -- the number of individuals to be selected 73 | (default len(population)) 74 | 75 | """ 76 | num_selected = args.setdefault('num_selected', len(population)) 77 | population.sort(reverse=True) 78 | return population[:num_selected] 79 | 80 | 81 | def uniform_selection(random, population, args): 82 | """Return a uniform sampling of individuals from the population. 83 | 84 | This function performs uniform selection by randomly choosing 85 | members of the population with replacement. 86 | 87 | .. Arguments: 88 | random -- the random number generator object 89 | population -- the population of individuals 90 | args -- a dictionary of keyword arguments 91 | 92 | Optional keyword arguments in args: 93 | 94 | - *num_selected* -- the number of individuals to be selected 95 | (default 1) 96 | 97 | """ 98 | num_selected = args.setdefault('num_selected', 1) 99 | selected = [] 100 | for _ in range(num_selected): 101 | selected.append(population[random.randint(0, len(population)-1)]) 102 | return selected 103 | 104 | 105 | def fitness_proportionate_selection(random, population, args): 106 | """Return fitness proportionate sampling of individuals from the population. 107 | 108 | This function stochastically chooses individuals from the population 109 | with probability proportional to their fitness. This is often 110 | referred to as "roulette wheel" selection. Note that this selection 111 | is not valid for minimization problems. 112 | 113 | .. Arguments: 114 | random -- the random number generator object 115 | population -- the population of individuals 116 | args -- a dictionary of keyword arguments 117 | 118 | Optional keyword arguments in args: 119 | 120 | - *num_selected* -- the number of individuals to be selected (default 1) 121 | 122 | """ 123 | num_selected = args.setdefault('num_selected', 1) 124 | len_pop = len(population) 125 | psum = [i for i in range(len_pop)] 126 | pop_max_fit = (max(population)).fitness 127 | pop_min_fit = (min(population)).fitness 128 | 129 | # If we're actually doing minimimization, 130 | # fitness proportionate selection is not defined. 131 | if pop_max_fit < pop_min_fit: 132 | raise ValueError('Fitness proportionate selection is not valid for minimization.') 133 | 134 | # Set up the roulette wheel 135 | if pop_max_fit == pop_min_fit: 136 | psum = [(index + 1) / float(len_pop) for index in range(len_pop)] 137 | elif (pop_max_fit > 0 and pop_min_fit >= 0) or (pop_max_fit <= 0 and pop_min_fit < 0): 138 | population.sort(reverse=True) 139 | psum[0] = population[0].fitness 140 | for i in range(1, len_pop): 141 | psum[i] = population[i].fitness + psum[i-1] 142 | for i in range(len_pop): 143 | psum[i] /= float(psum[len_pop-1]) 144 | 145 | # Select the individuals 146 | selected = [] 147 | for _ in range(num_selected): 148 | cutoff = random.random() 149 | lower = 0 150 | upper = len_pop - 1 151 | while(upper >= lower): 152 | mid = (lower + upper) // 2 153 | if psum[mid] > cutoff: 154 | upper = mid - 1 155 | else: 156 | lower = mid + 1 157 | lower = max(0, min(len_pop-1, lower)) 158 | selected.append(population[lower]) 159 | return selected 160 | 161 | 162 | def rank_selection(random, population, args): 163 | """Return a rank-based sampling of individuals from the population. 164 | 165 | This function behaves similarly to fitness proportionate selection, 166 | except that it uses the individual's rank in the population, rather 167 | than its raw fitness value, to determine its probability. This 168 | means that it can be used for both maximization and minimization 169 | problems, since higher rank can be defined correctly for both. 170 | 171 | .. Arguments: 172 | random -- the random number generator object 173 | population -- the population of individuals 174 | args -- a dictionary of keyword arguments 175 | 176 | Optional keyword arguments in args: 177 | 178 | - *num_selected* -- the number of individuals to be selected (default 1) 179 | 180 | """ 181 | num_selected = args.setdefault('num_selected', 1) 182 | 183 | # Set up the roulette wheel 184 | len_pop = len(population) 185 | population.sort() 186 | psum = list(range(len_pop)) 187 | den = (len_pop * (len_pop + 1)) / 2.0 188 | for i in range(len_pop): 189 | psum[i] = (i + 1) / den 190 | for i in range(1, len_pop): 191 | psum[i] += psum[i-1] 192 | 193 | # Select the individuals 194 | selected = [] 195 | for _ in range(num_selected): 196 | cutoff = random.random() 197 | lower = 0 198 | upper = len_pop - 1 199 | while(upper >= lower): 200 | mid = (lower + upper) // 2 201 | if psum[mid] > cutoff: 202 | upper = mid - 1 203 | else: 204 | lower = mid + 1 205 | lower = max(0, min(len_pop-1, lower)) 206 | selected.append(population[lower]) 207 | return selected 208 | 209 | 210 | def tournament_selection(random, population, args): 211 | """Return a tournament sampling of individuals from the population. 212 | 213 | This function selects ``num_selected`` individuals from the population. 214 | It selects each one by using random sampling without replacement 215 | to pull ``tournament_size`` individuals and adds the best of the 216 | tournament as its selection. If ``tournament_size`` is greater than 217 | the population size, the population size is used instead as the size 218 | of the tournament. 219 | 220 | .. Arguments: 221 | random -- the random number generator object 222 | population -- the population of individuals 223 | args -- a dictionary of keyword arguments 224 | 225 | Optional keyword arguments in args: 226 | 227 | - *num_selected* -- the number of individuals to be selected (default 1) 228 | - *tournament_size* -- the tournament size (default 2) 229 | 230 | """ 231 | num_selected = args.setdefault('num_selected', 1) 232 | tournament_size = args.setdefault('tournament_size', 2) 233 | if tournament_size > len(population): 234 | tournament_size = len(population) 235 | selected = [] 236 | for _ in range(num_selected): 237 | tourn = random.sample(population, tournament_size) 238 | selected.append(max(tourn)) 239 | return selected 240 | 241 | 242 | def constrained_tournament_selection(random, population, args): 243 | """Return a tournament sampling of individuals in consideration of the constraint 244 | violation from the population. 245 | 246 | This function selects ``num_selected`` individuals from the population. 247 | It selects each one by using random sampling without replacement 248 | to pull ``tournament_size`` individuals and adds the best of the 249 | tournament as its selection. If ``tournament_size`` is greater than 250 | the population size, the population size is used instead as the size 251 | of the tournament. 252 | 253 | author: Carola Paetzold 254 | 255 | .. Arguments: 256 | random -- the random number generator object 257 | population -- the population of individuals 258 | args -- a dictionary of keyword arguments 259 | 260 | Optional keyword arguments in args: 261 | 262 | - *num_selected* -- the number of individuals to be selected (default 1) 263 | - *tournament_size* -- the tournament size (default 2) 264 | 265 | """ 266 | 267 | from maphandler import constraint_tourn_selection 268 | selected = constraint_tourn_selection(random, population, args) 269 | return selected 270 | 271 | -------------------------------------------------------------------------------- /inspyred/swarm/swarm.py: -------------------------------------------------------------------------------- 1 | """ 2 | ================================== 3 | :mod:`swarm` -- Swarm intelligence 4 | ================================== 5 | 6 | This module provides standard swarm intelligence algorithms. 7 | 8 | .. Copyright 2012 Inspired Intelligence Initiative 9 | 10 | .. This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | .. This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | .. You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . 22 | 23 | .. module:: swarm 24 | .. moduleauthor:: Aaron Garrett 25 | """ 26 | import collections 27 | import copy 28 | import inspyred 29 | import math 30 | 31 | 32 | #----------------------------------------------------------------------- 33 | # PARTICLE SWARM OPTIMIZATION 34 | #----------------------------------------------------------------------- 35 | 36 | class PSO(inspyred.ec.EvolutionaryComputation): 37 | """Represents a basic particle swarm optimization algorithm. 38 | 39 | This class is built upon the ``EvolutionaryComputation`` class making 40 | use of an external archive and maintaining the population at the previous 41 | timestep, rather than a velocity. This approach was outlined in 42 | (Deb and Padhye, "Development of Efficient Particle Swarm Optimizers by 43 | Using Concepts from Evolutionary Algorithms", GECCO 2010, pp. 55--62). 44 | This class assumes that each candidate solution is a ``Sequence`` of 45 | real values. 46 | 47 | Public Attributes: 48 | 49 | - *topology* -- the neighborhood topology (default topologies.star_topology) 50 | 51 | Optional keyword arguments in ``evolve`` args parameter: 52 | 53 | - *inertia* -- the inertia constant to be used in the particle 54 | updating (default 0.5) 55 | - *cognitive_rate* -- the rate at which the particle's current 56 | position influences its movement (default 2.1) 57 | - *social_rate* -- the rate at which the particle's neighbors 58 | influence its movement (default 2.1) 59 | 60 | """ 61 | def __init__(self, random): 62 | inspyred.ec.EvolutionaryComputation.__init__(self, random) 63 | self.topology = inspyred.swarm.topologies.star_topology 64 | self._previous_population = [] 65 | self.selector = self._swarm_selector 66 | self.replacer = self._swarm_replacer 67 | self.variator = self._swarm_variator 68 | self.archiver = self._swarm_archiver 69 | 70 | def _swarm_archiver(self, random, population, archive, args): 71 | if len(archive) == 0: 72 | return population[:] 73 | else: 74 | new_archive = [] 75 | for i, (p, a) in enumerate(zip(population[:], archive[:])): 76 | if p < a: 77 | new_archive.append(a) 78 | else: 79 | new_archive.append(p) 80 | return new_archive 81 | 82 | def _swarm_variator(self, random, candidates, args): 83 | inertia = args.setdefault('inertia', 0.5) 84 | cognitive_rate = args.setdefault('cognitive_rate', 2.1) 85 | social_rate = args.setdefault('social_rate', 2.1) 86 | if len(self.archive) == 0: 87 | self.archive = self.population[:] 88 | if len(self._previous_population) == 0: 89 | self._previous_population = self.population[:] 90 | neighbors = self.topology(self._random, self.archive, args) 91 | offspring = [] 92 | for x, xprev, pbest, hood in zip(self.population, 93 | self._previous_population, 94 | self.archive, 95 | neighbors): 96 | nbest = max(hood) 97 | particle = [] 98 | for xi, xpi, pbi, nbi in zip(x.candidate, xprev.candidate, 99 | pbest.candidate, nbest.candidate): 100 | value = (xi + inertia * (xi - xpi) + 101 | cognitive_rate * random.random() * (pbi - xi) + 102 | social_rate * random.random() * (nbi - xi)) 103 | particle.append(value) 104 | particle = self.bounder(particle, args) 105 | offspring.append(particle) 106 | return offspring 107 | 108 | def _swarm_selector(self, random, population, args): 109 | return population 110 | 111 | def _swarm_replacer(self, random, population, parents, offspring, args): 112 | self._previous_population = population[:] 113 | return offspring 114 | 115 | 116 | #----------------------------------------------------------------------- 117 | # ANT COLONY OPTIMIZATION 118 | #----------------------------------------------------------------------- 119 | 120 | class TrailComponent(inspyred.ec.Individual): 121 | """Represents a discrete component of a trail in ant colony optimization. 122 | 123 | An trail component has an element, which is its essence (and which 124 | is equivalent to the candidate in the ``Individual`` parent class); 125 | a value, which is its weight or cost; a pheromone level; and a 126 | desirability, which is a combination of the value and pheromone 127 | level (and which is equivalent to the fitness in the ``Individual`` 128 | parent class). Note that the desirability (and, thus, the fitness) 129 | cannot be set manually. It is calculated automatically from the 130 | value and pheromone level. 131 | 132 | Public Attributes: 133 | 134 | - *element* -- the actual interpretation of this component 135 | - *value* -- the value or cost of the component 136 | - *desirability* -- the worth of the component based on value and 137 | pheromone level 138 | - *delta* -- the exponential contribution of the pheromone level on 139 | the desirability 140 | - *epsilon* -- the exponential contribution of the value on the 141 | desirability 142 | - *maximize* -- Boolean value stating use of maximization 143 | 144 | """ 145 | def __init__(self, element, value, maximize=True, delta=1, epsilon=1): 146 | inspyred.ec.Individual.__init__(self, element, maximize) 147 | self._value = value 148 | self._pheromone = 0 149 | self.fitness = 0 150 | self.delta = delta 151 | self.epsilon = epsilon 152 | 153 | @property 154 | def element(self): 155 | return self.candidate 156 | 157 | @element.setter 158 | def element(self, val): 159 | self.candidate = val 160 | 161 | @property 162 | def value(self): 163 | return self._value 164 | 165 | @value.setter 166 | def value(self, val): 167 | self._value = val 168 | self.fitness = (self._pheromone ** self.delta + 169 | self._value ** self.epsilon) 170 | 171 | @property 172 | def pheromone(self): 173 | return self._pheromone 174 | 175 | @pheromone.setter 176 | def pheromone(self, val): 177 | self._pheromone = val 178 | self.fitness = self._pheromone + self._value ** self.epsilon 179 | 180 | @property 181 | def desirability(self): 182 | return self.fitness 183 | 184 | def __eq__(self, other): 185 | return self.candidate == other.candidate 186 | 187 | def __str__(self): 188 | return '({0}, {1})'.format(self.element, self.value) 189 | 190 | def __repr__(self): 191 | return str(self) 192 | 193 | 194 | class ACS(inspyred.ec.EvolutionaryComputation): 195 | """Represents an Ant Colony System discrete optimization algorithm. 196 | 197 | This class is built upon the ``EvolutionaryComputation`` class making 198 | use of an external archive. It assumes that candidate solutions are 199 | composed of instances of ``TrailComponent``. 200 | 201 | Public Attributes: 202 | 203 | - *components* -- the full set of discrete components for a given problem 204 | - *initial_pheromone* -- the initial pheromone on a trail (default 0) 205 | - *evaporation_rate* -- the rate of pheromone evaporation (default 0.1) 206 | - *learning_rate* -- the learning rate used in pheromone updates 207 | (default 0.1) 208 | 209 | """ 210 | def __init__(self, random, components): 211 | inspyred.ec.EvolutionaryComputation.__init__(self, random) 212 | self.components = components 213 | self.evaporation_rate = 0.1 214 | self.initial_pheromone = 0 215 | self.learning_rate = 0.1 216 | self._variator = self._internal_variator 217 | self.archiver = self._internal_archiver 218 | self.replacer = inspyred.ec.replacers.generational_replacement 219 | 220 | @property 221 | def variator(self): 222 | return self._variator 223 | 224 | @variator.setter 225 | def variator(self, value): 226 | self._variator = [self._internal_variator] 227 | if isinstance(value, collections.Sequence): 228 | self._variator.extend(value) 229 | else: 230 | self._variator.append(value) 231 | 232 | def _internal_variator(self, random, candidates, args): 233 | offspring = [] 234 | for i in range(len(candidates)): 235 | offspring.append(self.generator(random, args)) 236 | return offspring 237 | 238 | def _internal_archiver(self, random, population, archive, args): 239 | best = max(population) 240 | if len(archive) == 0: 241 | archive.append(best) 242 | else: 243 | arc_best = max(archive) 244 | if best > arc_best: 245 | archive.remove(arc_best) 246 | archive.append(best) 247 | else: 248 | best = arc_best 249 | for c in self.components: 250 | c.pheromone = ((1 - self.evaporation_rate) * c.pheromone + 251 | self.evaporation_rate * self.initial_pheromone) 252 | for c in self.components: 253 | if c in best.candidate: 254 | c.pheromone = ((1 - self.learning_rate) * c.pheromone + 255 | self.learning_rate * best.fitness) 256 | return archive 257 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #------------------------------------------------------------------------------ 3 | # 4 | # Name: __init__.py 5 | # Purpose: This script includes the main function of the optimization tool. 6 | # It uses the inspyred package (http://inspyred.github.io/). 7 | # 8 | # Author: Carola Paetzold, Michael Strauch 9 | # Contact: michael.strauch@ufz.de 10 | # 11 | # Helmholtz Centre for Environmental Research - UFZ 12 | # Department Computational Landscape Ecology - CLE 13 | # Permoserstrasse 15 14 | # D-04318 Leipzig, Germany 15 | # http://www.ufz.de 16 | # 17 | # Created: Mar 19 2014 18 | # 19 | # Copyright: (c) Carola Paetzold, Michael Strauch 2018 20 | # 21 | # Licence: This program is free software: 22 | # you can redistribute it and/or modify it under the terms 23 | # of the GNU General Public License as published by the 24 | # Free Software Foundation, either version 3 of the License, 25 | # or (at your option) any later version. This program is 26 | # distributed in the hope that it will be useful, but 27 | # WITHOUT ANY WARRANTY; without even the implied warranty 28 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 29 | # See the GNU General Public License for more details. 30 | # You should have received a copy of the GNU General 31 | # Public License along with this program. 32 | # If not, see . 33 | # 34 | #------------------------------------------------------------------------------ 35 | 36 | #------------------------------------------------------------------------------ 37 | # Imports 38 | #------------------------------------------------------------------------------ 39 | import os 40 | import config as cfg 41 | import requirements as req 42 | import time 43 | import shutil 44 | import sys 45 | import distutils.core 46 | import argparse 47 | from argparse import ArgumentParser 48 | 49 | # ------------------------------------------------------------------------------ 50 | # Maximum number of threads as command line argument 51 | # ------------------------------------------------------------------------------ 52 | 53 | # defaults 54 | default_nthreads = "max cpu cores" 55 | 56 | # parsing arguments 57 | 58 | parser = ArgumentParser( 59 | description = 'CoMOLA - Constrained Multi-objective Optimization of Land use Allocation' 60 | ) 61 | 62 | parser.add_argument( 63 | "-t", "--threads", 64 | help = "number of threads to use, defaults to " + str(default_nthreads), 65 | dest = "nthreads", 66 | default = default_nthreads, 67 | metavar = 4 68 | ) 69 | 70 | options = parser.parse_args() 71 | 72 | # Get absolute path of this file 73 | wrkDir = os.path.abspath(".") 74 | 75 | #------------------------------------------------------------------------------------- 76 | # Update/delete the helping model folders 77 | #------------------------------------------------------------------------------------- 78 | def update_help_folders(fh): 79 | """Delete the helping model folders if cfg.modelConfig.del_help_folders = 'True' 80 | else update files/folders from cfg.modelConfig.update_filesx 81 | if this variable is not 'None' (default). 82 | 83 | """ 84 | 85 | if cfg.modelConfig.del_help_folders == 'True': 86 | # delete helping models folder 87 | fh.delete_models() 88 | else: 89 | # update files in helping model folders 90 | fh.WriteLogMsg("Update files in helping folders ...") 91 | i = 1 92 | folder_name = 'models_%s' %i 93 | while os.path.exists(os.path.join(wrkDir,folder_name)): 94 | for number in range(1,5): 95 | try: 96 | # if update_files is activated, check if files have changed; if so, update these files in the helping folders 97 | if number == 1: 98 | sub_folder = cfg.modelConfig.model1_folder 99 | update_files = cfg.modelConfig.update_files1 100 | elif number == 2: 101 | sub_folder = cfg.modelConfig.model2_folder 102 | update_files = cfg.modelConfig.update_files2 103 | elif number == 3: 104 | sub_folder = cfg.modelConfig.model3_folder 105 | update_files = cfg.modelConfig.update_files3 106 | else: 107 | sub_folder = cfg.modelConfig.model4_folder 108 | update_files = cfg.modelConfig.update_files4 109 | 110 | if update_files != 'None': 111 | for file in update_files.split(','): 112 | if os.path.isfile(os.path.join(wrkDir, folder_name, sub_folder, file)): 113 | if os.path.getmtime(os.path.join(wrkDir, folder_name, sub_folder, file)) \ 114 | != os.path.getmtime(os.path.join(wrkDir, 'models', sub_folder, file)): 115 | shutil.copy(os.path.join(wrkDir, 'models', sub_folder, file), \ 116 | os.path.join(wrkDir, folder_name, sub_folder, file)) 117 | elif os.path.isdir(os.path.join(wrkDir, folder_name, sub_folder, file)): 118 | if os.path.getmtime(os.path.join(wrkDir, folder_name, sub_folder, file)) \ 119 | != os.path.getmtime(os.path.join(wrkDir, 'models', sub_folder, file)): 120 | distutils.dir_util.copy_tree(os.path.join(wrkDir, 'models', sub_folder, file), \ 121 | os.path.join(wrkDir, folder_name, sub_folder, file)) 122 | # os.path.isfile(os.path.join(wrkDir, folder_name, sub_folder, file)) does not exist 123 | else: 124 | if os.path.isdir(os.path.join(wrkDir, 'models', sub_folder, file)): 125 | shutil.copytree(os.path.join(wrkDir, 'models', sub_folder, file), \ 126 | os.path.join(wrkDir, folder_name, sub_folder, file)) 127 | elif os.path.isfile(os.path.join(wrkDir, 'models', sub_folder, file)): 128 | shutil.copy(os.path.join(wrkDir, 'models', sub_folder, file), \ 129 | os.path.join(wrkDir, folder_name, sub_folder, file)) 130 | else: 131 | fh.WriteLogMsg("Path %s can`t be updated, because the original path does not exist. Please check config.ini." %os.path.join(wrkDir, 'models', sub_folder, file)) 132 | raise SystemError("Path %s can`t be updated, because the original path does not exist. Please check config.ini." %os.path.join(wrkDir, 'models', sub_folder, file)) 133 | req.close_window 134 | except: 135 | #print "Unexpected error:", sys.exc_info()[0] 136 | #raise 137 | break 138 | i += 1 139 | folder_name = 'models_%s' %i 140 | fh.WriteLogMsg("Update files is done.") 141 | 142 | #------------------------------------------------------------------------------ 143 | # Entry point - the main function 144 | #------------------------------------------------------------------------------ 145 | def main(): 146 | """Starts the optimization process.""" 147 | 148 | # get start time 149 | begin=time.time() 150 | 151 | print("number of threads: {}".format(options.nthreads)) 152 | 153 | # if a help file of a previous run exists, delete it 154 | if os.path.exists(os.path.join(wrkDir, "output", "help_file.txt")): 155 | os.remove(os.path.join(wrkDir, "output", "help_file.txt")) 156 | 157 | # check the Python version and requirements of the tool 158 | req.check_requirements() 159 | 160 | # if no exit activated until now, execute the next steps 161 | import optiAlgorithm 162 | import filehandler as fh 163 | 164 | # create an output folder for the log-files 165 | fh.create_output_folder() 166 | 167 | # initialize log file 168 | fh.InitLogFile() 169 | 170 | # save the input data 171 | fh.save_input_data() 172 | 173 | # inspyred logging for troubleshooting 174 | fh.inspyred_logging() 175 | 176 | # create a help file 177 | fh.save_timestamp(fh.timestamp_file) 178 | 179 | # check if helping folders should be created or if files should be updated 180 | update_help_folders(fh) 181 | 182 | # if repair_mutation is selected then special_termination should be selected too 183 | if 'repair_mutation' in cfg.ea.variator: 184 | if 'special_termination' not in cfg.ea.terminator: 185 | termination = cfg.ea.terminator 186 | termination = '%s,special_termination' % termination 187 | cfg.ea.terminator = termination 188 | fh.WriteLogMsg("Special_termination is added because of the selection of the repair_mutation.") 189 | 190 | # check if file is available with worst fitness values 191 | if cfg.mapConfig.file_worst_fitness == 'None' and (cfg.mapConfig.file_transformation != 'None' or cfg.mapConfig.file_difference!= 'None'): 192 | fh.WriteLogMsg("No input file available with worst fitness values. Please check config.ini.") 193 | raise SystemError("Error: No input file available with worst fitness values.") 194 | req.close_window 195 | 196 | # run optimization 197 | algorithm_selected = cfg.modelConfig.opt_algorithm 198 | msg = "Selected algorithm: %s" % algorithm_selected 199 | fh.WriteLogMsg(msg) 200 | 201 | if algorithm_selected == "GA": 202 | optiAlgorithm.GA() 203 | fh.plot_statistics_file() 204 | elif algorithm_selected == "NSGA2": 205 | optiAlgorithm.NSGA2() 206 | 207 | # delete the help file 208 | os.remove(os.path.join(wrkDir, "output", "help_file.txt")) 209 | 210 | # end time 211 | end=time.time() 212 | msg = "Total runtime of the tool: %d seconds." %(end-begin) 213 | fh.WriteLogMsg(msg) 214 | 215 | #------------------------------------------------------------------------------ 216 | # Call main function 217 | #------------------------------------------------------------------------------ 218 | if __name__ == "__main__": 219 | main() 220 | 221 | ############################################################################### 222 | # 223 | # EOF 224 | # 225 | ############################################################################### 226 | -------------------------------------------------------------------------------- /inspyred/ec/archivers.py: -------------------------------------------------------------------------------- 1 | """ 2 | ============================================= 3 | :mod:`archivers` -- Solution archival methods 4 | ============================================= 5 | 6 | This module provides pre-defined archivers for evoluationary computations. 7 | 8 | All archiver functions have the following arguments: 9 | 10 | - *random* -- the random number generator object 11 | - *population* -- the population of individuals 12 | - *archive* -- the current archive of individuals 13 | - *args* -- a dictionary of keyword arguments 14 | 15 | Each archiver function returns the updated archive. 16 | 17 | .. note:: 18 | 19 | The *population* is really a shallow copy of the actual population of 20 | the evolutionary computation. This means that any activities like 21 | sorting will not affect the actual population. 22 | 23 | .. Copyright 2012 Inspired Intelligence Initiative 24 | 25 | .. This program is free software: you can redistribute it and/or modify 26 | it under the terms of the GNU General Public License as published by 27 | the Free Software Foundation, either version 3 of the License, or 28 | (at your option) any later version. 29 | 30 | .. This program is distributed in the hope that it will be useful, 31 | but WITHOUT ANY WARRANTY; without even the implied warranty of 32 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 | GNU General Public License for more details. 34 | 35 | .. You should have received a copy of the GNU General Public License 36 | along with this program. If not, see . 37 | 38 | .. module:: archivers 39 | .. moduleauthor:: Aaron Garrett 40 | """ 41 | import math 42 | 43 | 44 | def default_archiver(random, population, archive, args): 45 | """Do nothing. 46 | 47 | This function just returns the existing archive (which is 48 | probably empty) with no changes. 49 | 50 | .. Arguments: 51 | random -- the random number generator object 52 | population -- the population of individuals 53 | archive -- the current archive of individuals 54 | args -- a dictionary of keyword arguments 55 | 56 | """ 57 | return archive 58 | 59 | 60 | def population_archiver(random, population, archive, args): 61 | """Archive the current population. 62 | 63 | This function replaces the archive with the individuals 64 | of the current population. 65 | 66 | .. Arguments: 67 | random -- the random number generator object 68 | population -- the population of individuals 69 | archive -- the current archive of individuals 70 | args -- a dictionary of keyword arguments 71 | 72 | """ 73 | new_archive = [] 74 | for ind in population: 75 | new_archive.append(ind) 76 | return new_archive 77 | 78 | 79 | def best_archiver(random, population, archive, args): 80 | """Archive only the best individual(s). 81 | 82 | This function archives the best solutions and removes inferior ones. 83 | If the comparison operators have been overloaded to define Pareto 84 | preference (as in the ``Pareto`` class), then this archiver will form 85 | a Pareto archive. 86 | 87 | .. Arguments: 88 | random -- the random number generator object 89 | population -- the population of individuals 90 | archive -- the current archive of individuals 91 | args -- a dictionary of keyword arguments 92 | 93 | """ 94 | new_archive = archive 95 | for ind in population: 96 | if len(new_archive) == 0: 97 | new_archive.append(ind) 98 | else: 99 | should_remove = [] 100 | should_add = True 101 | for a in new_archive: 102 | if ind.candidate == a.candidate: 103 | should_add = False 104 | break 105 | elif ind < a: 106 | should_add = False 107 | elif ind > a: 108 | should_remove.append(a) 109 | for r in should_remove: 110 | new_archive.remove(r) 111 | if should_add: 112 | new_archive.append(ind) 113 | return new_archive 114 | 115 | 116 | def adaptive_grid_archiver(random, population, archive, args): 117 | """Archive only the best individual(s) using a fixed size grid. 118 | 119 | This function archives the best solutions by using a fixed-size grid 120 | to determine which existing solutions should be removed in order to 121 | make room for new ones. This archiver is designed specifically for 122 | use with the Pareto Archived Evolution Strategy (PAES). 123 | 124 | .. Arguments: 125 | random -- the random number generator object 126 | population -- the population of individuals 127 | archive -- the current archive of individuals 128 | args -- a dictionary of keyword arguments 129 | 130 | Optional keyword arguments in args: 131 | 132 | - *max_archive_size* -- the maximum number of individuals in the archive 133 | (default len(population)) 134 | - *num_grid_divisions* -- the number of grid divisions (default 1) 135 | 136 | """ 137 | def get_grid_location(fitness, num_grid_divisions, global_smallest, global_largest): 138 | loc = 0 139 | n = 1 140 | num_objectives = len(fitness) 141 | inc = [0 for _ in range(num_objectives)] 142 | width = [0 for _ in range(num_objectives)] 143 | local_smallest = global_smallest[:] 144 | for i, f in enumerate(fitness): 145 | if f < local_smallest[i] or f > local_smallest[i] + global_largest[i] - global_smallest[i]: 146 | return -1 147 | for i in range(num_objectives): 148 | inc[i] = n 149 | n *= 2 150 | width[i] = global_largest[i] - global_smallest[i] 151 | for d in range(num_grid_divisions): 152 | for i, f in enumerate(fitness): 153 | if f < width[i] / 2.0 + local_smallest[i]: 154 | loc += inc[i] 155 | else: 156 | local_smallest[i] += width[i] / 2.0 157 | for i in range(num_objectives): 158 | inc[i] *= num_objectives * 2 159 | width[i] /= 2.0 160 | return loc 161 | 162 | def update_grid(individual, archive, num_grid_divisions, global_smallest, global_largest, grid_population): 163 | if len(archive) == 0: 164 | num_objectives = len(individual.fitness) 165 | smallest = [individual.fitness[o] for o in range(num_objectives)] 166 | largest = [individual.fitness[o] for o in range(num_objectives)] 167 | else: 168 | num_objectives = min(min([len(a.fitness) for a in archive]), len(individual.fitness)) 169 | smallest = [min(min([a.fitness[o] for a in archive]), individual.fitness[o]) for o in range(num_objectives)] 170 | largest = [max(max([a.fitness[o] for a in archive]), individual.fitness[o]) for o in range(num_objectives)] 171 | for i in range(num_objectives): 172 | global_smallest[i] = smallest[i] - abs(0.2 * smallest[i]) 173 | global_largest[i] = largest[i] + abs(0.2 * largest[i]) 174 | for i in range(len(grid_population)): 175 | grid_population[i] = 0 176 | for a in archive: 177 | loc = get_grid_location(a.fitness, num_grid_divisions, global_smallest, global_largest) 178 | a.grid_location = loc 179 | grid_population[loc] += 1 180 | loc = get_grid_location(individual.fitness, num_grid_divisions, global_smallest, global_largest) 181 | individual.grid_location = loc 182 | grid_population[loc] += 1 183 | 184 | max_archive_size = args.setdefault('max_archive_size', len(population)) 185 | num_grid_divisions = args.setdefault('num_grid_divisions', 1) 186 | 187 | if not 'grid_population' in dir(adaptive_grid_archiver): 188 | adaptive_grid_archiver.grid_population = [0 for _ in range(2**(min([len(p.fitness) for p in population]) * num_grid_divisions))] 189 | if not 'global_smallest' in dir(adaptive_grid_archiver): 190 | adaptive_grid_archiver.global_smallest = [0 for _ in range(min([len(p.fitness) for p in population]))] 191 | if not 'global_largest' in dir(adaptive_grid_archiver): 192 | adaptive_grid_archiver.global_largest = [0 for _ in range(min([len(p.fitness) for p in population]))] 193 | 194 | new_archive = archive 195 | for ind in population: 196 | update_grid(ind, new_archive, num_grid_divisions, adaptive_grid_archiver.global_smallest, 197 | adaptive_grid_archiver.global_largest, adaptive_grid_archiver.grid_population) 198 | should_be_added = True 199 | for a in new_archive: 200 | if ind == a or a > ind: 201 | should_be_added = False 202 | 203 | if should_be_added: 204 | if len(new_archive) == 0: 205 | new_archive.append(ind) 206 | else: 207 | join = False 208 | nondominated = True 209 | removal_set = [] 210 | for i, a in enumerate(new_archive): 211 | if ind > a and not join: 212 | new_archive[i] = ind 213 | join = True 214 | elif ind > a: 215 | if not a in removal_set: 216 | removal_set.append(a) 217 | # Otherwise, the individual is nondominated against this archive member. 218 | 219 | # We can't use set difference because Individual objects are not hashable. 220 | # We'd like to say... 221 | # new_archive = list(set(new_archive) - set(removal_set)) 222 | # So this code gets that same result without using sets. 223 | temp_archive = [] 224 | for ind in new_archive: 225 | if ind not in removal_set: 226 | temp_archive.append(ind) 227 | new_archive = temp_archive 228 | 229 | if not join and nondominated: 230 | if len(new_archive) == max_archive_size: 231 | replaced_index = 0 232 | found_replacement = False 233 | loc = get_grid_location(ind.fitness, num_grid_divisions, 234 | adaptive_grid_archiver.global_smallest, 235 | adaptive_grid_archiver.global_largest) 236 | ind.grid_location = loc 237 | if ind.grid_location >= 0: 238 | most = adaptive_grid_archiver.grid_population[ind.grid_location] 239 | else: 240 | most = -1 241 | for i, a in enumerate(new_archive): 242 | pop_at_a = adaptive_grid_archiver.grid_population[a.grid_location] 243 | if pop_at_a > most: 244 | most = pop_at_a 245 | replaced_index = i 246 | found_replacement = True 247 | if found_replacement: 248 | new_archive[replaced_index] = ind 249 | else: 250 | new_archive.append(ind) 251 | return new_archive 252 | -------------------------------------------------------------------------------- /inspyred/ec/variators/mutators.py: -------------------------------------------------------------------------------- 1 | """ 2 | =============== 3 | :mod:`mutators` 4 | =============== 5 | 6 | .. Copyright 2012 Inspired Intelligence Initiative 7 | 8 | .. This program is free software: you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation, either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | .. This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | .. You should have received a copy of the GNU General Public License 19 | along with this program. If not, see . 20 | 21 | .. module:: mutators 22 | .. moduleauthor:: Aaron Garrett 23 | """ 24 | import copy 25 | import functools 26 | 27 | 28 | def mutator(mutate): 29 | """Return an inspyred mutator function based on the given function. 30 | 31 | This function generator takes a function that operates on only 32 | one candidate to produce a single mutated candidate. The generator 33 | handles the iteration over each candidate in the set to be mutated. 34 | 35 | The given function ``mutate`` must have the following signature:: 36 | 37 | mutant = mutate(random, candidate, args) 38 | 39 | This function is most commonly used as a function decorator with 40 | the following usage:: 41 | 42 | @mutator 43 | def mutate(random, candidate, args): 44 | # Implementation of mutation 45 | pass 46 | 47 | The generated function also contains an attribute named 48 | ``single_mutation`` which holds the original mutation function. 49 | In this way, the original single-candidate function can be 50 | retrieved if necessary. 51 | 52 | """ 53 | @functools.wraps(mutate) 54 | def ecspy_mutator(random, candidates, args): 55 | mutants = [] 56 | for i, cs in enumerate(candidates): 57 | mutants.append(mutate(random, cs, args)) 58 | return mutants 59 | ecspy_mutator.single_mutation = mutate 60 | return ecspy_mutator 61 | 62 | 63 | @mutator 64 | def bit_flip_mutation(random, candidate, args): 65 | """Return the mutants produced by bit-flip mutation on the candidates. 66 | 67 | This function performs bit-flip mutation. If a candidate solution contains 68 | non-binary values, this function leaves it unchanged. 69 | 70 | .. Arguments: 71 | random -- the random number generator object 72 | candidate -- the candidate solution 73 | args -- a dictionary of keyword arguments 74 | 75 | Optional keyword arguments in args: 76 | 77 | - *mutation_rate* -- the rate at which mutation is performed (default 0.1) 78 | 79 | The mutation rate is applied on a bit by bit basis. 80 | 81 | """ 82 | rate = args.setdefault('mutation_rate', 0.1) 83 | mutant = copy.copy(candidate) 84 | if len(mutant) == len([x for x in mutant if x in [0, 1]]): 85 | for i, m in enumerate(mutant): 86 | if random.random() < rate: 87 | mutant[i] = (m + 1) % 2 88 | return mutant 89 | 90 | 91 | @mutator 92 | def random_reset_mutation(random, candidate, args): 93 | """Return the mutants produced by randomly choosing new values. 94 | 95 | This function performs random-reset mutation. It assumes that 96 | candidate solutions are composed of discrete values. This function 97 | makes use of the bounder function as specified in the EC's 98 | ``evolve`` method, and it assumes that the bounder contains 99 | an attribute called *values* (which is true for instances of 100 | ``DiscreteBounder``). 101 | 102 | The mutation moves through a candidate solution and, with rate 103 | equal to the *mutation_rate*, randomly chooses a value from the 104 | set of allowed values to be used in that location. Note that this 105 | value may be the same as the original value. 106 | 107 | .. Arguments: 108 | random -- the random number generator object 109 | candidate -- the candidate solution 110 | args -- a dictionary of keyword arguments 111 | 112 | Optional keyword arguments in args: 113 | 114 | - *mutation_rate* -- the rate at which mutation is performed (default 0.1) 115 | 116 | The mutation rate is applied on an element by element basis. 117 | 118 | """ 119 | bounder = args['_ec'].bounder 120 | try: 121 | values = bounder.values 122 | except AttributeError: 123 | values = None 124 | if values is not None: 125 | rate = args.setdefault('mutation_rate', 0.1) 126 | mutant = copy.copy(candidate) 127 | for i, m in enumerate(mutant): 128 | if random.random() < rate: 129 | mutant[i] = random.choice(values) 130 | return mutant 131 | else: 132 | return candidate 133 | 134 | 135 | @mutator 136 | def scramble_mutation(random, candidate, args): 137 | """Return the mutants created by scramble mutation on the candidates. 138 | 139 | This function performs scramble mutation. It randomly chooses two 140 | locations along the candidate and scrambles the values within that 141 | slice. 142 | 143 | .. Arguments: 144 | random -- the random number generator object 145 | candidate -- the candidate solution 146 | args -- a dictionary of keyword arguments 147 | 148 | Optional keyword arguments in args: 149 | 150 | - *mutation_rate* -- the rate at which mutation is performed (default 0.1) 151 | 152 | The mutation rate is applied to the candidate as a whole (i.e., it 153 | either mutates or it does not, based on the rate). 154 | 155 | """ 156 | rate = args.setdefault('mutation_rate', 0.1) 157 | if random.random() < rate: 158 | size = len(candidate) 159 | p = random.randint(0, size-1) 160 | q = random.randint(0, size-1) 161 | p, q = min(p, q), max(p, q) 162 | s = candidate[p:q+1] 163 | random.shuffle(s) 164 | return candidate[:p] + s[::-1] + candidate[q+1:] 165 | else: 166 | return candidate 167 | 168 | 169 | @mutator 170 | def inversion_mutation(random, candidate, args): 171 | """Return the mutants created by inversion mutation on the candidates. 172 | 173 | This function performs inversion mutation. It randomly chooses two 174 | locations along the candidate and reverses the values within that 175 | slice. 176 | 177 | .. Arguments: 178 | random -- the random number generator object 179 | candidate -- the candidate solution 180 | args -- a dictionary of keyword arguments 181 | 182 | Optional keyword arguments in args: 183 | 184 | - *mutation_rate* -- the rate at which mutation is performed (default 0.1) 185 | 186 | The mutation rate is applied to the candidate as a whole (i.e., it 187 | either mutates or it does not, based on the rate). 188 | 189 | """ 190 | rate = args.setdefault('mutation_rate', 0.1) 191 | if random.random() < rate: 192 | size = len(candidate) 193 | p = random.randint(0, size-1) 194 | q = random.randint(0, size-1) 195 | p, q = min(p, q), max(p, q) 196 | s = candidate[p:q+1] 197 | return candidate[:p] + s[::-1] + candidate[q+1:] 198 | else: 199 | return candidate 200 | 201 | 202 | @mutator 203 | def gaussian_mutation(random, candidate, args): 204 | """Return the mutants created by Gaussian mutation on the candidates. 205 | 206 | This function performs Gaussian mutation. This function 207 | makes use of the bounder function as specified in the EC's 208 | ``evolve`` method. 209 | 210 | .. Arguments: 211 | random -- the random number generator object 212 | candidate -- the candidate solution 213 | args -- a dictionary of keyword arguments 214 | 215 | Optional keyword arguments in args: 216 | 217 | - *mutation_rate* -- the rate at which mutation is performed (default 0.1) 218 | - *gaussian_mean* -- the mean used in the Gaussian function (default 0) 219 | - *gaussian_stdev* -- the standard deviation used in the Gaussian function 220 | (default 1) 221 | 222 | The mutation rate is applied on an element by element basis. 223 | 224 | """ 225 | mut_rate = args.setdefault('mutation_rate', 0.1) 226 | mean = args.setdefault('gaussian_mean', 0.0) 227 | stdev = args.setdefault('gaussian_stdev', 1.0) 228 | bounder = args['_ec'].bounder 229 | mutant = copy.copy(candidate) 230 | for i, m in enumerate(mutant): 231 | if random.random() < mut_rate: 232 | mutant[i] += random.gauss(mean, stdev) 233 | mutant = bounder(mutant, args) 234 | return mutant 235 | 236 | 237 | @mutator 238 | def nonuniform_mutation(random, candidate, args): 239 | """Return the mutants produced by nonuniform mutation on the candidates. 240 | 241 | The function performs nonuniform mutation as specified in 242 | (Michalewicz, "Genetic Algorithms + Data Structures = Evolution 243 | Programs," Springer, 1996). This function also makes use of the 244 | bounder function as specified in the EC's ``evolve`` method. 245 | 246 | .. note:: 247 | 248 | This function **requires** that *max_generations* be specified in 249 | the *args* dictionary. Therefore, it is best to use this operator 250 | in conjunction with the ``generation_termination`` terminator. 251 | 252 | .. Arguments: 253 | random -- the random number generator object 254 | candidate -- the candidate solution 255 | args -- a dictionary of keyword arguments 256 | 257 | Required keyword arguments in args: 258 | 259 | - *max_generations* -- the maximum number of generations for which 260 | evolution should take place 261 | 262 | Optional keyword arguments in args: 263 | 264 | - *mutation_strength* -- the strength of the mutation, where higher 265 | values correspond to greater variation (default 1) 266 | 267 | """ 268 | bounder = args['_ec'].bounder 269 | num_gens = args['_ec'].num_generations 270 | max_gens = args['max_generations'] 271 | strength = args.setdefault('mutation_strength', 1) 272 | exponent = (1.0 - num_gens / float(max_gens)) ** strength 273 | mutant = copy.copy(candidate) 274 | for i, (c, lo, hi) in enumerate(zip(candidate, bounder.lower_bound, bounder.upper_bound)): 275 | if random.random() <= 0.5: 276 | new_value = c + (hi - c) * (1.0 - random.random() ** exponent) 277 | else: 278 | new_value = c - (c - lo) * (1.0 - random.random() ** exponent) 279 | mutant[i] = new_value 280 | return mutant 281 | 282 | 283 | @mutator 284 | def filter_mutation(random, candidate, args): 285 | """Return the mutants produced by random generation and filtered on plausibility rules. 286 | 287 | This function performs the mutation via random generation and 288 | filter the mutant candidates on plausibility. 289 | 290 | author: Carola Paetzold 291 | 292 | .. Arguments: 293 | random -- the random number generator object 294 | candidate -- the candidate solution 295 | args -- a dictionary of keyword arguments 296 | 297 | """ 298 | 299 | from maphandler import generate_cand_filter 300 | mutant = generate_cand_filter(random, candidate, args) 301 | return mutant 302 | 303 | @mutator 304 | def repair_mutation(random, candidate, args): 305 | """Return the mutants produced from candidate with reparation of constraint violation. 306 | 307 | This function performs the mutation by repairing the candidate where constraints are violated. 308 | 309 | author: Carola Paetzold 310 | 311 | .. Arguments: 312 | random -- the random number generator object 313 | candidate -- the candidate solution 314 | args -- a dictionary of keyword arguments 315 | 316 | """ 317 | 318 | from maphandler import generate_cand_logical 319 | mutant = generate_cand_logical(random, candidate, args) 320 | return mutant 321 | -------------------------------------------------------------------------------- /inspyred/ec/terminators.py: -------------------------------------------------------------------------------- 1 | """ 2 | =================================================== 3 | :mod:`terminators` -- Algorithm termination methods 4 | =================================================== 5 | 6 | This module provides pre-defined terminators for evolutionary computations. 7 | 8 | Terminators specify when the evolutionary process should end. All 9 | terminators must return a Boolean value where True implies that 10 | the evolution should end. 11 | 12 | All terminator functions have the following arguments: 13 | 14 | - *population* -- the population of Individuals 15 | - *num_generations* -- the number of elapsed generations 16 | - *num_evaluations* -- the number of candidate solution evaluations 17 | - *args* -- a dictionary of keyword arguments 18 | 19 | .. note:: 20 | 21 | The *population* is really a shallow copy of the actual population of 22 | the evolutionary computation. This means that any activities like 23 | sorting will not affect the actual population. 24 | 25 | .. Copyright 2012 Inspired Intelligence Initiative 26 | 27 | .. This program is free software: you can redistribute it and/or modify 28 | it under the terms of the GNU General Public License as published by 29 | the Free Software Foundation, either version 3 of the License, or 30 | (at your option) any later version. 31 | 32 | .. This program is distributed in the hope that it will be useful, 33 | but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 35 | GNU General Public License for more details. 36 | 37 | .. You should have received a copy of the GNU General Public License 38 | along with this program. If not, see . 39 | 40 | .. module:: terminators 41 | .. moduleauthor:: Aaron Garrett 42 | """ 43 | import itertools 44 | import math 45 | import sys 46 | import time 47 | 48 | 49 | def default_termination(population, num_generations, num_evaluations, args): 50 | """Return True. 51 | 52 | This function acts as a default termination criterion for an evolutionary computation. 53 | 54 | .. Arguments: 55 | population -- the population of Individuals 56 | num_generations -- the number of elapsed generations 57 | num_evaluations -- the number of candidate solution evaluations 58 | args -- a dictionary of keyword arguments 59 | 60 | """ 61 | return True 62 | 63 | 64 | def diversity_termination(population, num_generations, num_evaluations, args): 65 | """Return True if population diversity is less than a minimum diversity. 66 | 67 | This function calculates the Euclidean distance between every pair of 68 | individuals in the population. It then compares the maximum of those 69 | distances with a specified minimum required diversity. This terminator 70 | is really only well-defined for candidate solutions which are list 71 | types of numeric values. 72 | 73 | .. Arguments: 74 | population -- the population of Individuals 75 | num_generations -- the number of elapsed generations 76 | num_evaluations -- the number of candidate solution evaluations 77 | args -- a dictionary of keyword arguments 78 | 79 | Optional keyword arguments in args: 80 | 81 | - *min_diversity* -- the minimum population diversity allowed (default 0.001) 82 | 83 | """ 84 | min_diversity = args.setdefault('min_diversity', 0.001) 85 | cart_prod = itertools.product(population, population) 86 | distance = [] 87 | for (p, q) in cart_prod: 88 | d = 0 89 | for x, y in zip(p.candidate, q.candidate): 90 | d += (x - y)**2 91 | distance.append(math.sqrt(d)) 92 | return max(distance) < min_diversity 93 | 94 | 95 | def average_fitness_termination(population, num_generations, num_evaluations, args): 96 | """Return True if the population's average fitness is near its best fitness. 97 | 98 | This function calculates the average fitness of the population, as well 99 | as the best fitness. If the difference between those values is less 100 | than a specified tolerance, the function returns True. 101 | 102 | .. Arguments: 103 | population -- the population of Individuals 104 | num_generations -- the number of elapsed generations 105 | num_evaluations -- the number of candidate solution evaluations 106 | args -- a dictionary of keyword arguments 107 | 108 | Optional keyword arguments in args: 109 | 110 | - *tolerance* -- the minimum allowable difference between average 111 | and best fitness (default 0.001) 112 | 113 | """ 114 | tolerance = args.setdefault('tolerance', 0.001) 115 | avg_fit = sum([x.fitness for x in population]) / float(len(population)) 116 | best_fit = max([x.fitness for x in population]) 117 | return (best_fit - avg_fit) < tolerance 118 | 119 | 120 | def evaluation_termination(population, num_generations, num_evaluations, args): 121 | """Return True if the number of function evaluations meets or exceeds a maximum. 122 | 123 | This function compares the number of function evaluations that have been 124 | generated with a specified maximum. It returns True if the maximum is met 125 | or exceeded. 126 | 127 | .. Arguments: 128 | population -- the population of Individuals 129 | num_generations -- the number of elapsed generations 130 | num_evaluations -- the number of candidate solution evaluations 131 | args -- a dictionary of keyword arguments 132 | 133 | Optional keyword arguments in args: 134 | 135 | - *max_evaluations* -- the maximum candidate solution evaluations (default 136 | len(population)) 137 | 138 | """ 139 | max_evaluations = args.setdefault('max_evaluations', len(population)) 140 | return num_evaluations >= max_evaluations 141 | 142 | 143 | def generation_termination(population, num_generations, num_evaluations, args): 144 | """Return True if the number of generations meets or exceeds a maximum. 145 | 146 | This function compares the number of generations with a specified 147 | maximum. It returns True if the maximum is met or exceeded. 148 | 149 | .. Arguments: 150 | population -- the population of Individuals 151 | num_generations -- the number of elapsed generations 152 | num_evaluations -- the number of candidate solution evaluations 153 | args -- a dictionary of keyword arguments 154 | 155 | Optional keyword arguments in args: 156 | 157 | - *max_generations* -- the maximum generations (default 1) 158 | 159 | """ 160 | max_generations = args.setdefault('max_generations', 1) 161 | return num_generations >= max_generations 162 | 163 | 164 | def time_termination(population, num_generations, num_evaluations, args): 165 | """Return True if the elapsed time meets or exceeds a duration of time. 166 | 167 | This function compares the elapsed time with a specified maximum. 168 | It returns True if the maximum is met or exceeded. If the `start_time` 169 | keyword argument is omitted, it defaults to `None` and will be set to 170 | the current system time (in seconds). If the `max_time` keyword argument 171 | is omitted, it will default to `None` and will immediately terminate. 172 | The `max_time` argument can be specified in seconds as a floating-point 173 | number, as minutes/seconds as a two-element tuple of floating-point 174 | numbers, or as hours/minutes/seconds as a three-element tuple of 175 | floating-point numbers. 176 | 177 | .. Arguments: 178 | population -- the population of Individuals 179 | num_generations -- the number of elapsed generations 180 | num_evaluations -- the number of candidate solution evaluations 181 | args -- a dictionary of keyword arguments 182 | 183 | Optional keyword arguments in args: 184 | 185 | - *start_time* -- the time from which to start measuring (default None) 186 | - *max_time* -- the maximum time that should elapse (default None) 187 | 188 | """ 189 | start_time = args.setdefault('start_time', None) 190 | max_time = args.setdefault('max_time', None) 191 | logging = args.get('_ec').logger 192 | 193 | if start_time is None: 194 | start_time = time.time() 195 | args['start_time'] = start_time 196 | logging.debug('time_termination terminator added without setting the start_time argument; setting start_time to current time') 197 | if max_time is None: 198 | logging.debug('time_termination terminator added without setting the max_time argument; terminator will immediately terminate') 199 | else: 200 | try: 201 | max_time = max_time[0] * 3600.0 + max_time[1] * 60.00 + max_time[2] 202 | args['max_time'] = max_time 203 | except TypeError: 204 | pass 205 | except IndexError: 206 | max_time = max_time[0] * 60 + max_time[1] 207 | args['max_time'] = max_time 208 | time_elapsed = time.time() - start_time 209 | return max_time is None or time_elapsed >= max_time 210 | 211 | 212 | def user_termination(population, num_generations, num_evaluations, args): 213 | """Return True if user presses the ESC key when prompted. 214 | 215 | This function prompts the user to press the ESC key to terminate the 216 | evolution. The prompt persists for a specified number of seconds before 217 | evolution continues. Additionally, the function can be customized to 218 | allow any press of the ESC key to be stored until the next time this 219 | function is called. 220 | 221 | .. note:: 222 | 223 | This function makes use of the ``msvcrt`` (Windows) and ``curses`` 224 | (Unix) libraries. Other systems may not be supported. 225 | 226 | .. Arguments: 227 | population -- the population of Individuals 228 | num_generations -- the number of elapsed generations 229 | num_evaluations -- the number of candidate solution evaluations 230 | args -- a dictionary of keyword arguments 231 | 232 | Optional keyword arguments in args: 233 | 234 | - *termination_response_timeout* -- the number of seconds to wait for 235 | the user to press the ESC key (default 5) 236 | - *clear_termination_buffer* -- whether the keyboard buffer should be 237 | cleared before allowing the user to press a key (default True) 238 | 239 | """ 240 | def getch(): 241 | unix = ('darwin', 'linux2') 242 | if sys.platform not in unix: 243 | try: 244 | import msvcrt 245 | except ImportError: 246 | return -1 247 | if msvcrt.kbhit(): 248 | return msvcrt.getch() 249 | else: 250 | return -1 251 | elif sys.platform in unix: 252 | def _getch(stdscr): 253 | stdscr.nodelay(1) 254 | ch = stdscr.getch() 255 | stdscr.nodelay(0) 256 | return ch 257 | import curses 258 | return curses.wrapper(_getch) 259 | 260 | num_secs = args.get('termination_response_timeout', 5) 261 | clear_buffer = args.get('clear_termination_buffer', True) 262 | if clear_buffer: 263 | while getch() > -1: 264 | pass 265 | sys.stdout.write('Press ESC to terminate (%d secs):' % num_secs) 266 | count = 1 267 | start = time.time() 268 | while time.time() - start < num_secs: 269 | ch = getch() 270 | if ch > -1 and ord(ch) == 27: 271 | sys.stdout.write('\n\n') 272 | return True 273 | elif time.time() - start == count: 274 | sys.stdout.write('.') 275 | count += 1 276 | sys.stdout.write('\n') 277 | return False 278 | 279 | def special_termination(population, num_generations, num_evaluations, args): 280 | """Return True. 281 | 282 | This function acts as a default termination criterion for an evolutionary computation. 283 | 284 | .. Arguments: 285 | population -- the population of Individuals 286 | num_generations -- the number of elapsed generations 287 | num_evaluations -- the number of candidate solution evaluations 288 | args -- a dictionary of keyword arguments 289 | 290 | """ 291 | from maphandler import logical_termination 292 | value = logical_termination() 293 | return value -------------------------------------------------------------------------------- /output_analysis/CoMOLA_postprocessing.R: -------------------------------------------------------------------------------- 1 | # Required packages 2 | # install.packages("raster") 3 | # install.packages("mco") 4 | # install.packages("plyr") 5 | # install.packages("ggplot2") 6 | # install.packages("viridis") 7 | 8 | library(mco) 9 | library(plyr) 10 | library(raster) 11 | library(ggplot2) 12 | library(viridis) 13 | library(here) 14 | 15 | ## Define paths 16 | # to optimization results 17 | opt_path <- here('output') 18 | 19 | # to some post-processing folder 20 | post_path <- here('output_analysis') 21 | 22 | # name of output metrics file 23 | file_out <- "metrics.txt" 24 | 25 | ### Extract results if any results are available and feasible 26 | setwd(opt_path) 27 | logfile<-file(dir(pattern="_log"),"r+") 28 | text<-readLines(logfile) 29 | close(logfile) 30 | 31 | if (any(grep("The optimization process needed", text) > 0)) { 32 | seconds <- strsplit(text[(grep("The optimization process needed", text))], "[|]") [[1]] [2] 33 | } 34 | 35 | if (any(grep("Best Solutions", text) > 0)) { 36 | bestsol <- as.matrix(text[(grep("Best Solutions", text)+2):(length(text)-1)]) 37 | infeasible <- grep("infeasible", bestsol) 38 | if (length(infeasible)>0) { 39 | feasible <- as.matrix(c(1:length(bestsol))[-infeasible]) 40 | bestsol <- as.matrix(bestsol[-infeasible]) 41 | } else (feasible <- c(1:length(bestsol))) 42 | if (length(bestsol)>0) { 43 | for(k in 1:length(bestsol)){ 44 | bestsol[k] <- strsplit(bestsol, "[|]") [[k]] [2] 45 | } 46 | } 47 | bestind <- bestsol 48 | bestfit <- bestsol 49 | if (length(bestsol)>0) { 50 | for(k in 1:length(bestsol)){ 51 | bestind[k] <- strsplit(bestsol, "[:]") [[k]] [1] 52 | bestind[k] <- substr(bestind[k], 3, nchar(bestind[k])-2) 53 | bestfit[k] <- strsplit(bestsol, "[:]") [[k]] [2] 54 | bestfit[k] <- substr(bestfit[k], 3, nchar(bestfit[k])-1) 55 | } 56 | } 57 | 58 | if(length(bestsol)>0){ 59 | setwd(post_path) 60 | write.table(file="bestind.txt",bestind, col.names=F, row.names=F, quote=F) 61 | write.table(file="bestfit.txt",bestfit, col.names=F, row.names=F, quote=F) 62 | write.table(file="seconds.txt",seconds, col.names=F, row.names=F, quote=F) 63 | write.table(file="feasible.txt",feasible, col.names=F, row.names=F, quote=F) 64 | } 65 | } 66 | 67 | ### get maps for single maxima and compromise solution 68 | # read in fitness values of best solutions 69 | best.sol <- read.table("bestfit.txt", h=F, sep =",") 70 | nobj <- length(best.sol) 71 | best.sol$ID <- c(1:dim(best.sol)[1]) 72 | 73 | if(nobj==2){ 74 | # extract only feasible solutions 75 | best.sol <- best.sol[which(best.sol$ID %in% feasible),] 76 | names(best.sol) <- c("obj1","obj2","ID") 77 | 78 | setwd(opt_path) 79 | # objective 1 80 | sol_max1 <- best.sol[which.max(best.sol$obj1),c(1:2)] 81 | ID_max1 <- best.sol[which.max(best.sol$obj1),3] 82 | map_max1 <- read.asc(dir(pattern=paste("map",ID_max1,".asc",sep="")), gz = FALSE) 83 | 84 | # objective 2 85 | sol_max2 <- best.sol[which.max(best.sol$obj2),c(1:2)] 86 | ID_max2 <- best.sol[which.max(best.sol$obj2),3] 87 | map_max2 <- read.asc(dir(pattern=paste("map",ID_max2,".asc",sep="")), gz = FALSE) 88 | 89 | # Compromise solution (sum of deviations from single mean values is minimal) 90 | which.mean <- function(x,y) which.min(abs(x - mean(x))+abs(y - mean(y))) 91 | sol_compromise <- best.sol[which.mean(best.sol$obj1,best.sol$obj2),c(1:2)] 92 | ID_compromise <- best.sol[which.mean(best.sol$obj1,best.sol$obj2),3] 93 | map_compromise <- read.asc(dir(pattern=paste("map",ID_compromise,".asc",sep="")), gz = FALSE) 94 | 95 | setwd(post_path) 96 | 97 | write.asc(map_max1, "map_max1.asc") 98 | write.asc(map_max2, "map_max2.asc") 99 | write.asc(map_compromise, "map_compromise.asc") 100 | } 101 | 102 | if(nobj==3){ 103 | # extract only feasible solutions 104 | best.sol <- best.sol[which(best.sol$ID %in% feasible),] 105 | names(best.sol) <- c("obj1","obj2","obj3","ID") 106 | 107 | ### get solutions for single maxima 108 | setwd(opt_path) 109 | # objective 1 110 | sol_max1 <- best.sol[which.max(best.sol$obj1),c(1:3)] 111 | ID_max1 <- best.sol[which.max(best.sol$obj1),4] 112 | map_max1 <- read.asc(dir(pattern=paste("map",ID_max1,".asc",sep="")), gz = FALSE) 113 | 114 | # objective 2 115 | sol_max2 <- best.sol[which.max(best.sol$obj2),c(1:3)] 116 | ID_max2 <- best.sol[which.max(best.sol$obj2),4] 117 | map_max2 <- read.asc(dir(pattern=paste("map",ID_max2,".asc",sep="")), gz = FALSE) 118 | 119 | # objective 3 120 | sol_max3 <- best.sol[which.max(best.sol$obj3),c(1:3)] 121 | ID_max3 <- best.sol[which.max(best.sol$obj3),4] 122 | map_max3 <- read.asc(dir(pattern=paste("map",ID_max3,".asc",sep="")), gz = FALSE) 123 | 124 | # Compromise solution (sum of deviations from single mean values is minimal) 125 | which.mean <- function(x,y) which.min(abs(x - mean(x))+abs(y - mean(y))+abs(z - mean(z))) 126 | sol_compromise <- best.sol[which.mean(best.sol$obj1,best.sol$obj2,best.sol$obj3),c(1:3)] 127 | ID_compromise <- best.sol[which.mean(best.sol$obj1,best.sol$obj2,best.sol$obj3),4] 128 | map_compromise <- read.asc(dir(pattern=paste("map",ID_compromise,".asc",sep="")), gz = FALSE) 129 | 130 | setwd(post_path) 131 | 132 | write.asc(map_max1, "map_max1.asc") 133 | write.asc(map_max2, "map_max2.asc") 134 | write.asc(map_max3, "map_max3.asc") 135 | write.asc(map_compromise, "map_compromise.asc") 136 | } 137 | 138 | if(nobj==4){ 139 | # extract only feasible solutions 140 | best.sol <- best.sol[which(best.sol$ID %in% feasible),] 141 | names(best.sol) <- c("obj1","obj2","obj3","obj4","ID") 142 | 143 | ### get solutions for single maxima 144 | setwd(opt_path) 145 | # objective 1 146 | sol_max1 <- best.sol[which.max(best.sol$obj1),c(1:4)] 147 | ID_max1 <- best.sol[which.max(best.sol$obj1),5] 148 | map_max1 <- read.asc(dir(pattern=paste("map",ID_max1,".asc",sep="")), gz = FALSE) 149 | 150 | # objective 2 151 | sol_max2 <- best.sol[which.max(best.sol$obj2),c(1:4)] 152 | ID_max2 <- best.sol[which.max(best.sol$obj2),5] 153 | map_max2 <- read.asc(dir(pattern=paste("map",ID_max2,".asc",sep="")), gz = FALSE) 154 | 155 | # objective 3 156 | sol_max3 <- best.sol[which.max(best.sol$obj3),c(1:4)] 157 | ID_max3 <- best.sol[which.max(best.sol$obj3),5] 158 | map_max3 <- read.asc(dir(pattern=paste("map",ID_max3,".asc",sep="")), gz = FALSE) 159 | 160 | # objective 4 161 | sol_max4 <- best.sol[which.max(best.sol$obj4),c(1:4)] 162 | ID_max4 <- best.sol[which.max(best.sol$obj4),5] 163 | map_max4 <- read.asc(dir(pattern=paste("map",ID_max4,".asc",sep="")), gz = FALSE) 164 | 165 | # Compromise solution (sum of deviations from single mean values is minimal) 166 | which.mean <- function(x,y) which.min(abs(x - mean(x))+abs(y - mean(y))+abs(z - mean(z))+abs(a - mean(a))) 167 | sol_compromise <- best.sol[which.mean(best.sol$obj1,best.sol$obj2,best.sol$obj3,best.sol$obj4),c(1:4)] 168 | ID_compromise <- best.sol[which.mean(best.sol$obj1,best.sol$obj2,best.sol$obj3,best.sol$obj4),5] 169 | map_compromise <- read.asc(dir(pattern=paste("map",ID_compromise,".asc",sep="")), gz = FALSE) 170 | 171 | setwd(post_path) 172 | 173 | write.asc(map_max1, "map_max1.asc") 174 | write.asc(map_max2, "map_max2.asc") 175 | write.asc(map_max3, "map_max3.asc") 176 | write.asc(map_max4, "map_max4.asc") 177 | write.asc(map_compromise, "map_compromise.asc") 178 | } 179 | 180 | ### Calculate performance measures 181 | ### Please note, they are only meaningful when comparing different runs 182 | 183 | is.integer0 <- function(x){ 184 | is.integer(x) && length(x) == 0L 185 | } 186 | 187 | calcMetrics <- function(path,file_out){ 188 | setwd(path) 189 | 190 | # get fitness values 191 | sol <- read.table("bestfit.txt",sep=",",h=F,as.is=T) 192 | 193 | ## calculate performance metrics for a 2-objective optimization 194 | if(length(sol)==2) { 195 | 196 | ref <- matrix(data=0,nrow=1, ncol=2) 197 | 198 | metrics <- data.frame(matrix(data=NA, nrow=1, ncol=5)) 199 | names(metrics) <- c("n","max1","max2","dHV","sec") 200 | 201 | # get number of solutions 202 | metrics[1,1] <- dim(sol)[1] 203 | 204 | # get single maxima 205 | metrics[1,2] <- round(max(sol[,1]),4) 206 | metrics[1,3] <- round(max(sol[,2]),4) 207 | 208 | # normalize for calculating the hypervolume 209 | sol.n <- sol 210 | sol.n[,1] <- sol[,1]/max(sol[,1]) 211 | sol.n[,2] <- sol[,2]/max(sol[,2]) 212 | 213 | # get dominated Hypervolume 214 | sol.val_ <- as.matrix(sol.n[,c(1:2)]*-1) 215 | pF <- paretoFront(sol.val_) 216 | pF_pos <- paretoFront(as.matrix(sol.n[,c(1:2)])) 217 | metrics[1,4] <- round(dominatedHypervolume(pF, ref),4) 218 | 219 | # get run time (seconds) 220 | sec <- read.table("seconds.txt",sep=" ",h=F,as.is=T) 221 | metrics[1,5] <- sec[6] 222 | 223 | write.table(metrics, file=file_out, col.names=T, row.names=F, quote=F) 224 | } 225 | 226 | ## calculate performance metrics for a 3-objective optimization 227 | if(length(sol)==3) { 228 | 229 | ref <- matrix(data=0,nrow=1, ncol=3) 230 | 231 | metrics <- data.frame(matrix(data=NA, nrow=1, ncol=6)) 232 | names(metrics) <- c("n","max1","max2","max3","dHV","sec") 233 | 234 | # get number of solutions 235 | metrics[1,1] <- dim(sol)[1] 236 | 237 | # get single maxima 238 | metrics[1,2] <- round(max(sol[,1]),4) 239 | metrics[1,3] <- round(max(sol[,2]),4) 240 | metrics[1,4] <- round(max(sol[,3]),4) 241 | 242 | # normalize for calculating the hypervolume 243 | sol.n <- sol 244 | sol.n[,1] <- sol[,1]/max(sol[,1]) 245 | sol.n[,2] <- sol[,2]/max(sol[,2]) 246 | sol.n[,3] <- sol[,3]/max(sol[,3]) 247 | 248 | # get dominated Hypervolume 249 | sol.val_ <- as.matrix(sol.n[,c(1:3)]*-1) 250 | pF <- paretoFront(sol.val_) 251 | pF_pos <- paretoFront(as.matrix(sol.n[,c(1:3)])) 252 | metrics[1,5] <- round(dominatedHypervolume(pF, ref),4) 253 | 254 | # get run time (seconds) 255 | sec <- read.table("seconds.txt",sep=" ",h=F,as.is=T) 256 | metrics[1,6] <- sec[6] 257 | 258 | write.table(metrics, file=file_out, col.names=T, row.names=F, quote=F) 259 | } 260 | ## calculate performance metrics for a 4-objective optimization 261 | if(length(sol)==4) { 262 | 263 | ref <- matrix(data=0,nrow=1, ncol=4) 264 | 265 | metrics <- data.frame(matrix(data=NA, nrow=1, ncol=7)) 266 | names(metrics) <- c("n","max1","max2","max3","max4","dHV","sec") 267 | 268 | # get number of solutions 269 | metrics[1,1] <- dim(sol)[1] 270 | 271 | # get single maxima 272 | metrics[1,2] <- round(max(sol[,1]),4) 273 | metrics[1,3] <- round(max(sol[,2]),4) 274 | metrics[1,4] <- round(max(sol[,3]),4) 275 | metrics[1,5] <- round(max(sol[,4]),4) 276 | 277 | # normalize for hypervolume calculation 278 | sol.n <- sol 279 | sol.n[,1] <- sol[,1]/max(sol[,1]) 280 | sol.n[,2] <- sol[,2]/max(sol[,2]) 281 | sol.n[,3] <- sol[,3]/max(sol[,3]) 282 | sol.n[,4] <- sol[,4]/max(sol[,4]) 283 | 284 | # get dominated Hypervolume 285 | sol.val_ <- as.matrix(sol.n[,c(1:4)]*-1) 286 | pF <- paretoFront(sol.val_) 287 | pF_pos <- paretoFront(as.matrix(sol.n[,c(1:4)])) 288 | metrics[1,6] <- round(dominatedHypervolume(pF, ref),4) 289 | 290 | # get run time (seconds) 291 | sec <- read.table("seconds.txt",sep=" ",h=F,as.is=T) 292 | metrics[1,7] <- sec[6] 293 | 294 | write.table(metrics, file=file_out, col.names=T, row.names=F, quote=F) 295 | } 296 | } 297 | 298 | # apply function 299 | calcMetrics(post_path, file_out) 300 | 301 | 302 | ### Plot results 303 | # 2D version, maybe only an option if there are not too many solutions 304 | # (if there are too many solutions you may use a filter) 305 | setwd(post_path) 306 | sol <- read.table("bestfit.txt",sep=",",h=F,as.is=T) 307 | 308 | # plot for 2 objectives 309 | if(length(sol)==2){ 310 | names(sol) <- c("obj1","obj2") 311 | ggplot(sol, aes(x=obj1, y=obj2)) + 312 | geom_point(aes(), shape=21, col="black") + 313 | xlab("Objective 1")+ 314 | ylab("Objective 2") 315 | } 316 | 317 | # plot for 3 objectives 318 | if(length(sol)==3){ 319 | names(sol) <- c("obj1","obj2","obj3") 320 | ggplot(sol, aes(x=obj1, y=obj2)) + 321 | geom_point(aes(fill=obj3), shape=21, col="black") + 322 | scale_fill_gradientn(colours=viridis(100)) + 323 | guides(fill = guide_legend(title="Objective 3")) + 324 | xlab("Objective 1")+ 325 | ylab("Objective 2") 326 | } 327 | 328 | # plot for 4 objectives 329 | if(length(sol)==4){ 330 | names(sol) <- c("obj1","obj2","obj3","obj4") 331 | ggplot(sol, aes(x=obj1, y=obj2)) + 332 | geom_point(aes(size=obj4, fill=obj3), shape=21, col="black") + 333 | scale_fill_gradientn(colours=viridis(100)) + 334 | guides(size = guide_legend(title="Objective 4", override.aes = list(col = "black")), 335 | fill = guide_legend(title="Objective 3")) + 336 | xlab("Objective 1")+ 337 | ylab("Objective 2") 338 | } 339 | 340 | -------------------------------------------------------------------------------- /inspyred/ec/analysis.py: -------------------------------------------------------------------------------- 1 | """ 2 | =============================================== 3 | :mod:`analysis` -- Optimization result analysis 4 | =============================================== 5 | 6 | This module provides analysis methods for the results of evolutionary computations. 7 | 8 | .. Copyright 2012 Inspired Intelligence Initiative 9 | 10 | .. This program is free software: you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation, either version 3 of the License, or 13 | (at your option) any later version. 14 | 15 | .. This program is distributed in the hope that it will be useful, 16 | but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | GNU General Public License for more details. 19 | 20 | .. You should have received a copy of the GNU General Public License 21 | along with this program. If not, see . 22 | 23 | .. module:: analysis 24 | .. moduleauthor:: Aaron Garrett 25 | """ 26 | import csv 27 | import math 28 | 29 | def fitness_statistics(population): 30 | """Return the basic statistics of the population's fitness values. 31 | 32 | This function returns a dictionary containing the "best", "worst", 33 | "mean", "median", and "std" fitness values in the population. 34 | ("std" is the standard deviation.) A typical usage would be similar 35 | to the following:: 36 | 37 | stats = fitness_statistics(population) 38 | print(stats['best']) 39 | print(stats['worst']) 40 | print(stats['mean']) 41 | print(stats['median']) 42 | print(stats['std']) 43 | 44 | .. note:: 45 | 46 | This function makes use of the numpy library for calculations. If that 47 | library is not found, it attempts to complete the calculations 48 | internally. However, this second attempt will fail for multiobjective 49 | fitness values and will return ``nan`` for the mean, median, and 50 | standard deviation. 51 | 52 | Arguments: 53 | 54 | - *population* -- the population of individuals 55 | 56 | """ 57 | population.sort(reverse=True) 58 | worst_fit = population[-1].fitness 59 | best_fit = population[0].fitness 60 | try: 61 | import numpy 62 | f = [p.fitness for p in population] 63 | med_fit = numpy.median(f) 64 | avg_fit = numpy.mean(f) 65 | std_fit = numpy.std(f) 66 | except ImportError: 67 | try: 68 | plen = len(population) 69 | if plen % 2 == 1: 70 | med_fit = population[(plen - 1) // 2].fitness 71 | else: 72 | med_fit = float(population[plen // 2 - 1].fitness + population[plen // 2].fitness) / 2 73 | avg_fit = sum([p.fitness for p in population]) / float(plen) 74 | if plen > 1: 75 | std_fit = math.sqrt(sum([(p.fitness - avg_fit)**2 for p in population]) / float(plen - 1)) 76 | else: 77 | std_fit = 0 78 | except TypeError: 79 | med_fit = float('nan') 80 | avg_fit = float('nan') 81 | std_fit = float('nan') 82 | return {'best': best_fit, 'worst': worst_fit, 'mean': avg_fit, 83 | 'median': med_fit, 'std': std_fit} 84 | 85 | 86 | def generation_plot(filename, errorbars=True): 87 | """Plot the results of the algorithm using generation statistics. 88 | 89 | This function creates a plot of the generation fitness statistics 90 | (best, worst, median, and average). This function requires the 91 | pylab and matplotlib libraries. 92 | 93 | .. note:: 94 | 95 | This function only works for single-objective problems. 96 | 97 | .. figure:: _static/generation_plot.png 98 | :alt: Example generation plot 99 | :align: center 100 | 101 | An example image saved from the ``generation_plot`` function (without error bars). 102 | 103 | Arguments: 104 | 105 | - *filename* -- the name of the statistics file produced by the file_observer 106 | - *errorbars* -- Boolean value stating whether standard error bars should 107 | be drawn (default True) 108 | 109 | """ 110 | import pylab 111 | import matplotlib.font_manager 112 | 113 | generation = [] 114 | psize = [] 115 | worst = [] 116 | best = [] 117 | median = [] 118 | average = [] 119 | stdev = [] 120 | reader = csv.reader(open(filename)) 121 | for row in reader: 122 | generation.append(int(row[0])) 123 | psize.append(int(row[1])) 124 | worst.append(float(row[2])) 125 | best.append(float(row[3])) 126 | median.append(float(row[4])) 127 | average.append(float(row[5])) 128 | stdev.append(float(row[6])) 129 | stderr = [s / math.sqrt(p) for s, p in zip(stdev, psize)] 130 | 131 | data = [average, median, best, worst] 132 | colors = ['black', 'blue', 'green', 'red'] 133 | labels = ['average', 'median', 'best', 'worst'] 134 | figure = pylab.figure() 135 | if errorbars: 136 | pylab.errorbar(generation, average, stderr, color=colors[0], label=labels[0]) 137 | else: 138 | pylab.plot(generation, average, color=colors[0], label=labels[0]) 139 | for d, col, lab in zip(data[1:], colors[1:], labels[1:]): 140 | pylab.plot(generation, d, color=col, label=lab) 141 | pylab.fill_between(generation, data[2], data[3], color='#e6f2e6') 142 | pylab.grid(True) 143 | ymin = min([min(d) for d in data]) 144 | ymax = max([max(d) for d in data]) 145 | yrange = ymax - ymin 146 | pylab.ylim((ymin - 0.1*yrange, ymax + 0.1*yrange)) 147 | prop = matplotlib.font_manager.FontProperties(size=8) 148 | pylab.legend(loc='upper left', prop=prop) 149 | pylab.xlabel('Generation') 150 | pylab.ylabel('Fitness') 151 | pylab.show() 152 | 153 | 154 | def allele_plot(filename, normalize=False, alleles=None, generations=None): 155 | """Plot the alleles from each generation from the individuals file. 156 | 157 | This function creates a plot of the individual allele values as they 158 | change through the generations. It creates three subplots, one for each 159 | of the best, median, and average individual. The best and median 160 | individuals are chosen using the fitness data for each generation. The 161 | average individual, on the other hand, is actually an individual created 162 | by averaging the alleles within a generation. This function requires the 163 | pylab library. 164 | 165 | .. note:: 166 | 167 | This function only works for single-objective problems. 168 | 169 | .. figure:: _static/allele_plot.png 170 | :alt: Example allele plot 171 | :align: center 172 | 173 | An example image saved from the ``allele_plot`` function. 174 | 175 | Arguments: 176 | 177 | - *filename* -- the name of the individuals file produced by the file_observer 178 | - *normalize* -- Boolean value stating whether allele values should be 179 | normalized before plotting (default False) 180 | - *alleles* -- a list of allele index values that should be plotted 181 | (default None) 182 | - *generations* -- a list of generation numbers that should be plotted 183 | (default None) 184 | 185 | If *alleles* is ``None``, then all alleles are plotted. Similarly, if 186 | *generations* is ``None``, then all generations are plotted. 187 | 188 | """ 189 | import pylab 190 | 191 | generation_data = [] 192 | reader = csv.reader(open(filename)) 193 | for row in reader: 194 | g = int(row[0]) 195 | row[3] = row[3].replace('[', '') 196 | row[-1] = row[-1].replace(']', '') 197 | individual = [float(r) for r in row[3:]] 198 | individual.append(float(row[2])) 199 | try: 200 | generation_data[g] 201 | except IndexError: 202 | generation_data.append([]) 203 | generation_data[g].append(individual) 204 | for gen in generation_data: 205 | gen.sort(key=lambda x: x[-1]) 206 | for j, g in enumerate(gen): 207 | gen[j] = g[:-1] 208 | 209 | best = [] 210 | median = [] 211 | average = [] 212 | for gen in generation_data: 213 | best.append(gen[0]) 214 | plen = len(gen) 215 | if plen % 2 == 1: 216 | med = gen[(plen - 1) // 2] 217 | else: 218 | med = [] 219 | for a, b in zip(gen[plen // 2 - 1], gen[plen // 2]): 220 | med.append(float(a + b) / 2) 221 | median.append(med) 222 | avg = [0] * len(gen[0]) 223 | for individual in gen: 224 | for i, allele in enumerate(individual): 225 | avg[i] += allele 226 | for i, a in enumerate(avg): 227 | avg[i] /= float(len(gen)) 228 | average.append(avg) 229 | 230 | for plot_num, (data, title) in enumerate(zip([best, median, average], 231 | ["Best", "Median", "Average"])): 232 | if alleles is None: 233 | alleles = list(range(len(data[0]))) 234 | if generations is None: 235 | generations = list(range(len(data))) 236 | if normalize: 237 | columns = list(zip(*data)) 238 | max_col = [max(c) for c in columns] 239 | min_col = [min(c) for c in columns] 240 | for dat in data: 241 | for i, d in enumerate(dat): 242 | dat[i] = (d - min_col[i]) / float(max_col[i] - min_col[i]) 243 | plot_data = [] 244 | for g in generations: 245 | plot_data.append([data[g][a] for a in alleles]) 246 | sub = pylab.subplot(3, 1, plot_num + 1) 247 | pylab.pcolor(pylab.array(plot_data)) 248 | pylab.colorbar() 249 | step_size = max(len(generations) // 7, 1) 250 | ytick_locs = list(range(step_size, len(generations), step_size)) 251 | ytick_labs = generations[step_size::step_size] 252 | pylab.yticks(ytick_locs, ytick_labs) 253 | pylab.ylabel('Generation') 254 | if plot_num == 2: 255 | xtick_locs = list(range(len(alleles))) 256 | xtick_labs = alleles 257 | pylab.xticks(xtick_locs, xtick_labs) 258 | pylab.xlabel('Allele') 259 | else: 260 | pylab.setp(sub.get_xticklabels(), visible=False) 261 | pylab.title(title) 262 | pylab.show() 263 | 264 | 265 | def hypervolume(pareto_set, reference_point=None): 266 | """Calculates the hypervolume by slicing objectives (HSO). 267 | 268 | This function calculates the hypervolume (or S-measure) of a nondominated 269 | set using the Hypervolume by Slicing Objectives (HSO) procedure of `While, et al. 270 | (IEEE CEC 2005) `_. 271 | The *pareto_set* should be a list of lists of objective values. 272 | The *reference_point* may be specified or it may be left as the default 273 | value of None. In that case, the reference point is calculated to be the 274 | maximum value in the set for all objectives (the ideal point). This function 275 | assumes that objectives are to be maximized. 276 | 277 | Arguments: 278 | 279 | - *pareto_set* -- the list or lists of objective values comprising the Pareto front 280 | - *reference_point* -- the reference point to be used (default None) 281 | 282 | """ 283 | def dominates(p, q, k=None): 284 | if k is None: 285 | k = len(p) 286 | d = True 287 | while d and k < len(p): 288 | d = not (q[k] > p[k]) 289 | k += 1 290 | return d 291 | 292 | def insert(p, k, pl): 293 | ql = [] 294 | while pl and pl[0][k] > p[k]: 295 | ql.append(pl[0]) 296 | pl = pl[1:] 297 | ql.append(p) 298 | while pl: 299 | if not dominates(p, pl[0], k): 300 | ql.append(pl[0]) 301 | pl = pl[1:] 302 | return ql 303 | 304 | def slice(pl, k, ref): 305 | p = pl[0] 306 | pl = pl[1:] 307 | ql = [] 308 | s = [] 309 | while pl: 310 | ql = insert(p, k + 1, ql) 311 | p_prime = pl[0] 312 | s.append((math.fabs(p[k] - p_prime[k]), ql)) 313 | p = p_prime 314 | pl = pl[1:] 315 | ql = insert(p, k + 1, ql) 316 | s.append((math.fabs(p[k] - ref[k]), ql)) 317 | return s 318 | 319 | ps = pareto_set 320 | ref = reference_point 321 | n = min([len(p) for p in ps]) 322 | if ref is None: 323 | ref = [max(ps, key=lambda x: x[o])[o] for o in range(n)] 324 | pl = ps[:] 325 | pl.sort(key=lambda x: x[0], reverse=True) 326 | s = [(1, pl)] 327 | for k in range(n - 1): 328 | s_prime = [] 329 | for x, ql in s: 330 | for x_prime, ql_prime in slice(ql, k, ref): 331 | s_prime.append((x * x_prime, ql_prime)) 332 | s = s_prime 333 | vol = 0 334 | for x, ql in s: 335 | vol = vol + x * math.fabs(ql[0][n - 1] - ref[n - 1]) 336 | return vol 337 | 338 | 339 | 340 | 341 | 342 | --------------------------------------------------------------------------------