Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the DDS algorithm for spotpy #195

Merged
merged 79 commits into from
Feb 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
cbca7cf
Start writing dds in python. Very raw version
bees4ever Sep 13, 2018
9367e52
short before substitution with own random handler
bees4ever Sep 13, 2018
cce2dbf
Working version, which is same as Matlab, extended with own random funcs
bees4ever Sep 13, 2018
9d1e04b
Add new class FixedrRandom to control randomized algorithms in Matlab…
bees4ever Sep 17, 2018
017d34a
Add a version unready version of DDS algorithm. *datawriter* and *obj…
bees4ever Sep 17, 2018
9e73b37
Add first unittest for DDS to compare Matlab vs Python output
bees4ever Sep 17, 2018
0f57b0b
Merge branch 'master' into DDS_new_algorithm
bees4ever Sep 17, 2018
b3a36cb
implement distinct parameters sampling in DDS with spotpy's parameter…
bees4ever Sep 18, 2018
8464e4f
Add more tests, reorganize pytest for DDS
bees4ever Sep 20, 2018
df28595
little bugfixes more descriptions
bees4ever Sep 20, 2018
b42398e
use get_fitness to calculate objective function the spotpy way
bees4ever Sep 20, 2018
30e1d64
finish user's parameter initialization and write unittests
bees4ever Sep 20, 2018
d3cc3c0
Some more unittests concerning own parameter initialization
bees4ever Sep 20, 2018
e541862
Refactor loop to postprocess correct simulation and parameters
bees4ever Nov 1, 2018
58c610f
Refactor sample method and clean up comments
bees4ever Nov 1, 2018
38a1f1f
DDS: Refactoring variable names and use BestValue classs
bees4ever Nov 11, 2018
e298ba7
DDS: refctor generator
bees4ever Nov 11, 2018
3aa8444
Start writing dds in python. Very raw version
bees4ever Sep 13, 2018
bb7fad7
short before substitution with own random handler
bees4ever Sep 13, 2018
e562c94
Working version, which is same as Matlab, extended with own random funcs
bees4ever Sep 13, 2018
218155e
Add new class FixedrRandom to control randomized algorithms in Matlab…
bees4ever Sep 17, 2018
0e1a9ed
Add a version unready version of DDS algorithm. *datawriter* and *obj…
bees4ever Sep 17, 2018
be3dded
Add first unittest for DDS to compare Matlab vs Python output
bees4ever Sep 17, 2018
685caf0
implement distinct parameters sampling in DDS with spotpy's parameter…
bees4ever Sep 18, 2018
d2ea777
Add more tests, reorganize pytest for DDS
bees4ever Sep 20, 2018
67d981f
little bugfixes more descriptions
bees4ever Sep 20, 2018
83ee09c
use get_fitness to calculate objective function the spotpy way
bees4ever Sep 20, 2018
a1b272d
finish user's parameter initialization and write unittests
bees4ever Sep 20, 2018
5627488
Some more unittests concerning own parameter initialization
bees4ever Sep 20, 2018
ae3f505
Refactor loop to postprocess correct simulation and parameters
bees4ever Nov 1, 2018
b35a94d
Refactor sample method and clean up comments
bees4ever Nov 1, 2018
5b20463
DDS: Refactoring variable names and use BestValue classs
bees4ever Nov 11, 2018
b6fc42d
DDS: refctor generator
bees4ever Nov 11, 2018
cfdf151
Merge branch 'New-Algorithm-DDS' of https://github.com/bees4ever/spot…
bees4ever Nov 11, 2018
2bf8910
Start writing dds in python. Very raw version
bees4ever Sep 13, 2018
37bb488
short before substitution with own random handler
bees4ever Sep 13, 2018
e77fb61
Working version, which is same as Matlab, extended with own random funcs
bees4ever Sep 13, 2018
5cf9642
Add new class FixedrRandom to control randomized algorithms in Matlab…
bees4ever Sep 17, 2018
bbef883
Add a version unready version of DDS algorithm. *datawriter* and *obj…
bees4ever Sep 17, 2018
e217536
Add first unittest for DDS to compare Matlab vs Python output
bees4ever Sep 17, 2018
231afd4
implement distinct parameters sampling in DDS with spotpy's parameter…
bees4ever Sep 18, 2018
45a66fc
Add more tests, reorganize pytest for DDS
bees4ever Sep 20, 2018
4e61df5
little bugfixes more descriptions
bees4ever Sep 20, 2018
d019ac3
use get_fitness to calculate objective function the spotpy way
bees4ever Sep 20, 2018
45b0438
finish user's parameter initialization and write unittests
bees4ever Sep 20, 2018
82d0876
Some more unittests concerning own parameter initialization
bees4ever Sep 20, 2018
881881a
Refactor loop to postprocess correct simulation and parameters
bees4ever Nov 1, 2018
5cde391
Refactor sample method and clean up comments
bees4ever Nov 1, 2018
2997f43
DDS: Refactoring variable names and use BestValue classs
bees4ever Nov 11, 2018
0d9ad00
DDS: refctor generator
bees4ever Nov 11, 2018
730cea5
Start writing dds in python. Very raw version
bees4ever Sep 13, 2018
3981aac
short before substitution with own random handler
bees4ever Sep 13, 2018
0625f94
Working version, which is same as Matlab, extended with own random funcs
bees4ever Sep 13, 2018
96d5f98
Add new class FixedrRandom to control randomized algorithms in Matlab…
bees4ever Sep 17, 2018
10136d1
Add first unittest for DDS to compare Matlab vs Python output
bees4ever Sep 17, 2018
c80b50a
use get_fitness to calculate objective function the spotpy way
bees4ever Sep 20, 2018
b350f55
Refactor sample method and clean up comments
bees4ever Nov 1, 2018
4027eba
DDS: Refactoring variable names and use BestValue classs
bees4ever Nov 11, 2018
3656ee1
Merge branch 'New-Algorithm-DDS' of https://github.com/bees4ever/spot…
bees4ever Nov 11, 2018
2484f0b
DDS: fix rebase
bees4ever Nov 11, 2018
bbbd92f
Merge branch 'master' into New-Algorithm-DDS
bees4ever Nov 20, 2018
637af65
Introduce BestValue in combination with ParameterSet. Propose a copy …
bees4ever Nov 20, 2018
c21fcda
Introduce BestValue in combination with ParameterSet. Propose a copy …
bees4ever Nov 20, 2018
4977eac
Merge branch 'New-Algorithm-DDS' of https://github.com/bees4ever/spot…
bees4ever Nov 20, 2018
a54dd53
Always maximize in BestValue and DDS. Tidy up BestValue.
bees4ever Nov 20, 2018
858a5ce
use distinct flag in parameter class
bees4ever Nov 21, 2018
257fe62
fix `astuple` method in parameter class
bees4ever Nov 21, 2018
1532f1b
refactor DDS: use a DDSGenerator
bees4ever Nov 21, 2018
0fe5a5a
fix parameter unittest
bees4ever Nov 21, 2018
d79480c
tidy up py.test outputs
bees4ever Nov 21, 2018
c561390
finalize DDS and update tutorial_dds.py
bees4ever Nov 23, 2018
5beb76b
Add first DDS Benchmarks
bees4ever Jan 18, 2019
fe4d881
DDS parallel tests and results
bees4ever Jan 25, 2019
1e07e2c
force specific package versions for travis
bees4ever Jan 27, 2019
c3a0dd2
Merge branch 'master' into New-Algorithm-DDS
bees4ever Jan 29, 2019
c688607
- refactor DDS Algorithm
bees4ever Feb 1, 2019
c2e78ec
DDS: use self.status and not BestValue class
bees4ever Feb 2, 2019
733fc01
try to fix travis
bees4ever Feb 2, 2019
2a81c06
some python 2 type errors
bees4ever Feb 2, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ wheels/
.installed.cfg
*.egg

# Python Unittest tool `py.test`
.pytest_cache/*

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
Expand Down
3 changes: 2 additions & 1 deletion spotpy/algorithms/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@
from .abc import abc # Artificial Bee Colony
from .fscabc import fscabc # Fitness Scaling Artificial Bee Colony
from .dream import dream # DiffeRential Evolution Adaptive Metropolis
from .list_sampler import list_sampler # Samples from given spotpy database
from .list_sampler import list_sampler # Samples from given spotpy database
from .dds import dds # Dynamically Dimensioned Search algorithm by Bryan Tolson.
389 changes: 389 additions & 0 deletions spotpy/algorithms/dds.py

Large diffs are not rendered by default.

117 changes: 117 additions & 0 deletions spotpy/examples/dds/benchmark_dds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from pprint import pprint
import numpy as np
import matplotlib.pylab as plt
import json

import time

try:
import spotpy
except ImportError:
import sys

sys.path.append(".")
import spotpy

from spotpy.examples.spot_setup_hymod_python import spot_setup



spot_setup = spot_setup()

# Create samplers for every algorithm:
results = []

benchmarks_dict = []
benchmarks_duration = {"dds":[], "sceua":[], "dds_like":[],"sceua_like":[]}
reps = [300, 1000, 3000, 4000, 5000, 10000]


for rep in reps:

timeout = 10 # Given in Seconds

parallel = "seq"
dbformat = "csv"

start = time.time()
dds_sampler = spotpy.algorithms.DDS(spot_setup, parallel=parallel, dbname='DDS', dbformat=dbformat, sim_timeout=timeout)
dds_sampler.sample(rep, trials=1)
results.append(dds_sampler.getdata())
dds_elapsed = time.time() - start

start = time.time()
sceua_sampler = spotpy.algorithms.sceua(spot_setup, parallel=parallel, dbname='SCEUA', dbformat=dbformat,
sim_timeout=timeout, alt_objfun=None)
sceua_sampler.sample(rep)
results.append(sceua_sampler.getdata())
sceua_elapsed = time.time() - start


print("#########################################")

#print(dds_elapsed, dds_sampler.status.params)

print(sceua_elapsed, sceua_sampler.status.params)

benchmarks_dict.append({
"rep": rep,
"dds_time": dds_elapsed,
"sceua_time": sceua_elapsed,
"dds_like": dds_sampler.status.objectivefunction,
"sceua_like": sceua_sampler.status.objectivefunction,
"dds_param": list(dds_sampler.status.params),
"sceua_param": list(sceua_sampler.status.params)
})
benchmarks_duration["dds"].append(dds_elapsed)
benchmarks_duration["sceua"].append(sceua_elapsed)
benchmarks_duration["sceua_like"].append(sceua_sampler.status.objectivefunction)
benchmarks_duration["dds_like"].append(dds_sampler.status.objectivefunction)

print(json.dumps(benchmarks_dict))


def autolabel(rects):
"""
Attach a text label above each bar displaying its height
"""
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width()/2., 1.05*height,
'%d' % int(height),
ha='center', va='bottom')



fig = plt.figure(figsize=(10, 6))
ax = plt.subplot(111)

rep_labels = [str(j) for j in reps]
x_pos = [i for i, _ in enumerate(rep_labels)]


X = np.arange(len(benchmarks_duration["dds"]))
dds_plot = ax.bar(x_pos, benchmarks_duration["dds_like"], color = 'b', width = 0.45)
sceua_plot = ax.bar([j+0.45 for j in x_pos], benchmarks_duration["sceua_like"], color = 'g', width = 0.45)

#dds_plot = ax.bar(x_pos, benchmarks_duration["dds"], color = 'b', width = 0.45)
#sceua_plot = ax.bar([j+0.45 for j in x_pos], benchmarks_duration["sceua"], color = 'g', width = 0.45)



plt.xticks(x_pos, rep_labels)
plt.legend(("DDS", "SCEUA"))
plt.xlabel("Repetitions")
plt.ylabel("Best Objective Function Value")

autolabel(dds_plot)
autolabel(sceua_plot)

plt.show()
plt.savefig("MPI_TEST")
#

46 changes: 46 additions & 0 deletions spotpy/examples/dds/dds_parallel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import numpy as np
import sys
import os
import matplotlib.pylab as plt
import json
import time

try:
import spotpy
except ImportError:
import sys

sys.path.append(".")
import spotpy

from spotpy.examples.spot_setup_hymod_python import spot_setup

spot_setup = spot_setup()


path = os.path.abspath(os.path.dirname(__file__))
json_path = path + "/dds_parallel_data.json"
benchmarks_duration = json.load(open(json_path))


rep = int(sys.argv[1])
timeout = 10 # Given in Seconds
parallel = "mpi"
dbformat = "csv"
start = time.time()
dds_sampler = spotpy.algorithms.dds(spot_setup, parallel=parallel, dbname='DDS', dbformat=dbformat, sim_timeout=timeout)
dds_sampler.sample(rep, trials=1)
dds_elapsed = time.time() - start
print(dds_elapsed)

benchmarks_duration["dds_duration"].append(dds_elapsed)
benchmarks_duration["dds_like"].append(dds_sampler.status.objectivefunction)
benchmarks_duration["rep"].append(rep)

print(benchmarks_duration)

json.dump(benchmarks_duration, open(json_path,"w"))
51 changes: 51 additions & 0 deletions spotpy/examples/dds/dds_parallel_plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import numpy as np

import matplotlib.pylab as plt
import json
import matplotlib as mp

data_normalizer = mp.colors.Normalize()
color_map = mp.colors.LinearSegmentedColormap(
"my_map",
{
"red": [(0, 1.0, 1.0),
(1.0, .5, .5)],
"green": [(0, 0.5, 0.5),
(1.0, 0, 0)],
"blue": [(0, 0.50, 0.5),
(1.0, 0, 0)]
}
)


def autolabel(ax, rects):
"""
Attach a text label above each bar displaying its height
"""
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height,
'%f' % height,
ha='center', va='bottom')


def subplot(data, name, ylabel):
fig = plt.figure(figsize=(20, 6))
ax = plt.subplot(111)
rep_labels = [str(j) for j in reps]
x_pos = [i for i, _ in enumerate(rep_labels)]
X = np.arange(len(data))
ax_plot = ax.bar(x_pos, data, color=color_map(data_normalizer(data)), width=0.45)

plt.xticks(x_pos, rep_labels)
plt.xlabel("Repetitions")
plt.ylabel(ylabel)

autolabel(ax, ax_plot)
plt.savefig(name + ".png")


parallel_data = json.loads('{"dds_duration": [1.1293659210205078, 3.254117250442505, 4.888171672821045, 18.719818592071533, 34.56907820701599, 169.47716689109802, 337.86882615089417, 1644.955144405365, 3348.948029756546], "rep": [30, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000], "dds_like": [-8384.884435178812, -8269.480874403698, -8268.453892284442, -8268.51195094138, -8269.65509041187, -8268.1421690868, -8267.791798085422, -8267.79178644684, -8268.141980514703]}')
reps = parallel_data["rep"]
subplot(parallel_data["dds_duration"], "DDS_PARALLEL_DURATION_all", "Duration of Run in Seconds")
subplot(parallel_data["dds_like"], "DDS_PARALLEL_OBJECTIVEFUNCTION_all", "Best Objective Function Value")
8 changes: 8 additions & 0 deletions spotpy/examples/dds/dds_parallel_run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import subprocess
import os
path = os.path.abspath(os.path.dirname(__file__))
for r in [500,1000,5000,10000,50000,100000,500000]:
args = ["mpirun", "-c 6", "python", path + "/dds_parallel.py", str(r)]
print(args)
subprocess.run(args)
exit(8)
83 changes: 83 additions & 0 deletions spotpy/examples/spot_setup_dds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import spotpy
from spotpy.parameter import Uniform
from spotpy.objectivefunctions import rmse
import numpy as np


def ackley10(vector):
length = len(vector)
sum1 = 0
sum2 = 0
for i in range(length):
sum1 = sum1 + vector[i] ** 2
sum2 = sum2 + np.cos(2 * np.pi * vector[i])
return -1*(-20 * np.exp(-0.2 * (sum1 / length) ** 0.5) - np.exp(sum2 / length))


def griewank10(vector):
sum1 = 0
term2 = 1
term3 = 1

for i in range(len(vector)):
sum1 = sum1 + (vector[i] ** 2) / 4000
term2 = term2 * np.cos(vector[i] / (i + 1) ** 0.5)

return -1*(sum1 - term2 + term3)


class spot_setup(object):
"""
Setup for a simple example to run DDS Algorithm
"""

def __init__(self):
self.params = None
self.objfunc = None

def _objfunc_switcher(self, name):
"""
Set new parameter and objective function while setup is instanced in a test case
:param name: function name which overwrites initial objective function
:return:
"""

if name == "ackley":
self.objfunc = ackley10
self.params = [Uniform(str(j), -2, 2, 1.5, 3.0, -2, 2, doc=str(j) + ' value of Rosenbrock function')
for j in range(10)]
elif name == "griewank":
self.objfunc = griewank10
self.params = [Uniform('d' + str(j), -500, 700, 1.5, 3.0, -500, 700,
doc=str(j) + 'distinc parameter within a boundary', as_int=True)
for j in range(2)] + [Uniform('c' + str(j), -500, 700, 1.5, 3.0, -500, 700,
doc=str(j) + 'continuous parameter within a boundary')
for j in range(8)]

def parameters(self):
if self.params is None:
self.params = [
Uniform("0", -10, 10, 1.5, 3.0, -10, 10, doc='x value of Rosenbrock function'),
Uniform("1", -10, 10, 1.5, 3.0, -10, 10, doc='y value of Rosenbrock function'),
Uniform("z", -10, 10, 1.5, 3.0, -10, 10, doc='z value of Rosenbrock function')]
return spotpy.parameter.generate(self.params)

def simulation(self, vector):
x = np.array(vector)
# simulations = [sum(100.0 * (x[1:] - x[:-1] ** 2.0) ** 2.0 + (1 - x[:-1]) ** 2.0)]
simulations = x * np.random.rand(len(vector))
#simulations = x * np.sum(vector)
return simulations

def evaluation(self):
# observations = [0]
observations = [2, 3, 4]
return observations

def objectivefunction(self, simulation, evaluation, params):

if self.objfunc is None:
return -1*rmse(evaluation, simulation)
else:
pars, names = params
return self.objfunc(pars)
Loading