├── .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 |
--------------------------------------------------------------------------------