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

Adding ModCMA environment #41

Merged
merged 9 commits into from
Feb 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ tests/data/
test/*.json

# pycharm specific stuff
.idea
.idea


venv
settings.json
*egg
32 changes: 17 additions & 15 deletions dacbench/abstract_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ def save_config(self, path):
and -np.inf not in conf[k][i]
):
conf[k][i] = list(map(int, conf[k][i]))
elif isinstance(conf[k],np.ndarray):
conf[k] = conf[k].tolist()

conf["wrappers"] = self.jsonify_wrappers()

Expand Down Expand Up @@ -201,9 +203,12 @@ def read_config_file(self, path):
if "observation_space_type" in self.config:
# Types have to be numpy dtype (for gym spaces)s
if type(self.config["observation_space_type"]) == str:
typestring = self.config["observation_space_type"].split(" ")[1][:-2]
typestring = typestring.split(".")[1]
self.config["observation_space_type"] = getattr(np, typestring)
if self.config["observation_space_type"] == "None":
self.config["observation_space_type"] = None
else:
typestring = self.config["observation_space_type"].split(" ")[1][:-2]
typestring = typestring.split(".")[1]
self.config["observation_space_type"] = getattr(np, typestring)
if "observation_space" in self.config:
self.config["observation_space"] = self.list_to_space(
self.config["observation_space"]
Expand Down Expand Up @@ -307,18 +312,15 @@ class objdict(dict):
"""
Modified dict to make config changes more flexible
"""

__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__

def copy(self):
return objdict(**super().copy())

def __getattr__(self, name):
if name in self:
return self[name]
else:
raise AttributeError("No such attribute: " + name)

def __setattr__(self, name, value):
self[name] = value



def __delattr__(self, name):
if name in self:
del self[name]
else:
raise AttributeError("No such attribute: " + name)
122 changes: 122 additions & 0 deletions dacbench/additional_configs/onell/configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"""
All configs for the (1+(lambda, lambda)) Genetic Algorithms
To generate the .json config files in this folder, run: export_all_configs_to_json()
"""

from copy import copy
from dacbench.abstract_benchmark import objdict, AbstractBenchmark
import numpy as np
import json

INFO = {
"identifier": "onell",
"name": "OneLL-GA benchmark",
"reward": "",
"state_description": [""]
}

"""
Setting 1a:
Name: lbd_theory
Description:
The simplest setting where we only tune lbd and assume that p=lambda/n and c=1/lambda
The optimal policy for OneMax is lambda = sqrt(n / (n-f(x))), where:
n is problem size
f(x) is current objective value
State space: n (int), f(x) (int)
Action space: lbd (int)
"""
onell_lbd_theory = objdict(
{
"name": "lbd_theory",
"action_space_class": "Box",
"action_space_args": [np.array([1]), np.array([np.inf])],
"action_description": "lbd",
"observation_space_class": "Box",
"observation_space_type": np.int32,
"observation_space_args": [
np.array([1, 0]),
np.array([np.inf, np.inf])
],
"observation_description": "n, f(x)",
"reward_range": [-np.inf, np.inf], # the true reward range is instance dependent
"cutoff": 1e9, # we don't really use this,
# the real cutoff is in instance_set_path and is instance dependent
"include_xprime": True, # if True, xprime is included in the selection after crossover phase
"count_different_inds_only": True, # if True, only count an evaluation of a child if it is different from both of its parents
"seed": 0,
"problem": "OneMax",
"instance_set_path": "../instance_sets/onell/onemax_2000.csv",
"benchmark_info": INFO
}
)

# Setting 1b:
# Name: lbd_onefifth
# Description:
# Same as setting 1a but with slightly different state-space (n, delta f(x), lambda_{t-1})
# In this setting, the agent can learn the best policy for OneMax using the 1/5th rule:
# if delta f(x) = f(x_t) - f(x_{t-1}) <= 0: lambda_t = min{(3/2)^1/4 * lambda_{t-1}, n-1}
# otherwise: lambda_t = max{2/3 * lambda_{t-1}, 1}
onell_lbd_onefifth = copy(onell_lbd_theory)
onell_lbd_onefifth["name"] = "lbd_onefifth"
onell_lbd_onefifth["observation_space_type"] = np.float32
onell_lbd_onefifth["observation_space_args"] = [np.array([1, 0, 1]), np.array([np.inf, np.inf, np.inf])]
onell_lbd_onefifth["observation_description"] = "n, delta f(x), lbd_{t-1}"


# Setting 2:
# Name: lbd_p_c
# Description: a more sophisticated setting where we tune lambda, p and c together
# State space: n (int), f(x) (int), delta f(x) (int), lambda_{t-1}, p_{t-1}, c_{t-1}
# action space: lambda (int), p (float), c (float)
onell_lbd_p_c = copy(onell_lbd_theory)
onell_lbd_p_c["name"] = "lbd_p_c"
onell_lbd_p_c["observation_space_type"] = np.float32
onell_lbd_p_c["observation_space_args"] = [np.array([1, 0, 0, 1, 0, 0]), np.array([np.inf, np.inf, np.inf, np.inf, 1, 1])]
onell_lbd_p_c["action_space_args"] = [np.array([1, 0, 0]), np.array([np.inf, 1, 1])]
onell_lbd_p_c["action_description"] = "lbd, p, c"
onell_lbd_p_c["observation_description"] = "n, f(x), delta f(x), lbd_{t-1}, p_{t-1}, c_{t-1}"

# Setting 3:
# Name: lbd1_lbd2_p_c
# Description: a setting where we tune lambda1 (#mutated off-springs), lambda2 (#crossovered off-springs), p and c together
# State space: n (int), f(x) (int), delta f(x) (int), lambda1_{t-1}, lambda2_{t-1}, p_{t-1}, c_{t-1}
# action space: lambda1 (int), lambda2 (int), p (float), c (float)
onell_lbd1_lbd2_p_c = copy(onell_lbd_theory)
onell_lbd1_lbd2_p_c["name"] = "lbd1_lbd2_p_c"
onell_lbd1_lbd2_p_c["observation_space_type"] = np.float32
onell_lbd1_lbd2_p_c["observation_space_args"] = [np.array([1, 0, 0, 1, 1, 0, 0]), np.array([np.inf, np.inf, np.inf, np.inf, np.inf, 1, 1])]
onell_lbd1_lbd2_p_c["action_space_args"] = [np.array([1, 1, 0, 0]), np.array([np.inf, np.inf, 1, 1])]
onell_lbd1_lbd2_p_c["action_description"] = "lbd1, lbd2, p, c"
onell_lbd1_lbd2_p_c["observation_description"] = "n, f(x), delta f(x), lbd1_{t-1}, lbd2_{t-1}, p_{t-1}, c_{t-1}"

def config_to_json(config_name, json_file=None):
"""
Write a config to json file

Parameters
---------
config_name: str
accept values: one of the configs defined above
json_file: str
output .json file name. If None, will be set as <config_name>.json
"""
if json_file is None:
json_file = config_name + ".json"

with open(json_file, 'wt') as f:
bench = AbstractBenchmark()
bench.config = globals()['onell_' + config_name]
bench.save_config(json_file)


def export_all_configs_to_json(output_dir = './'):
"""
Export all configs above to json files
"""
for config_name in ['lbd_theory', 'lbd_onefifth', 'lbd_p_c', 'lbd1_lbd2_p_c']:
config_to_json(config_name, json_file=output_dir + '/' + config_name + '.json')


#export_all_configs_to_json()
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/lbd1_lbd2_p_c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd1_lbd2_p_c", "action_space_class": "Box", "action_space_args": [[1, 1, 0, 0], [Infinity, Infinity, 1.0, 1.0]], "action_description": "lbd1, lbd2, p, c", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.float32'>", "observation_space_args": [[1, 0, 0, 1, 1, 0, 0], [Infinity, Infinity, Infinity, Infinity, Infinity, 1.0, 1.0]], "observation_description": "n, f(x), delta f(x), lbd1_{t-1}, lbd2_{t-1}, p_{t-1}, c_{t-1}", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/lbd_onefifth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd_onefifth", "action_space_class": "Box", "action_space_args": [[1], [Infinity]], "action_description": "lbd", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.float32'>", "observation_space_args": [[1, 0, 1], [Infinity, Infinity, Infinity]], "observation_description": "n, delta f(x), lbd_{t-1}", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/lbd_p_c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd_p_c", "action_space_class": "Box", "action_space_args": [[1, 0, 0], [Infinity, 1.0, 1.0]], "action_description": "lbd, p, c", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.float32'>", "observation_space_args": [[1, 0, 0, 1, 0, 0], [Infinity, Infinity, Infinity, Infinity, 1.0, 1.0]], "observation_description": "n, f(x), delta f(x), lbd_{t-1}, p_{t-1}, c_{t-1}", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/lbd_theory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd_theory", "action_space_class": "Box", "action_space_args": [[1], [Infinity]], "action_description": "lbd", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.int32'>", "observation_space_args": [[1, 0], [Infinity, Infinity]], "observation_description": "n, f(x)", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
122 changes: 122 additions & 0 deletions dacbench/additional_configs/onell/onell/configs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"""
All configs for the (1+(lambda, lambda)) Genetic Algorithms
To generate the .json config files in this folder, run: export_all_configs_to_json()
"""

from copy import copy
from dacbench.abstract_benchmark import objdict, AbstractBenchmark
import numpy as np
import json

INFO = {
"identifier": "onell",
"name": "OneLL-GA benchmark",
"reward": "",
"state_description": [""]
}

"""
Setting 1a:
Name: lbd_theory
Description:
The simplest setting where we only tune lbd and assume that p=lambda/n and c=1/lambda
The optimal policy for OneMax is lambda = sqrt(n / (n-f(x))), where:
n is problem size
f(x) is current objective value
State space: n (int), f(x) (int)
Action space: lbd (int)
"""
onell_lbd_theory = objdict(
{
"name": "lbd_theory",
"action_space_class": "Box",
"action_space_args": [np.array([1]), np.array([np.inf])],
"action_description": "lbd",
"observation_space_class": "Box",
"observation_space_type": np.int32,
"observation_space_args": [
np.array([1, 0]),
np.array([np.inf, np.inf])
],
"observation_description": "n, f(x)",
"reward_range": [-np.inf, np.inf], # the true reward range is instance dependent
"cutoff": 1e9, # we don't really use this,
# the real cutoff is in instance_set_path and is instance dependent
"include_xprime": True, # if True, xprime is included in the selection after crossover phase
"count_different_inds_only": True, # if True, only count an evaluation of a child if it is different from both of its parents
"seed": 0,
"problem": "OneMax",
"instance_set_path": "../instance_sets/onell/onemax_2000.csv",
"benchmark_info": INFO
}
)

# Setting 1b:
# Name: lbd_onefifth
# Description:
# Same as setting 1a but with slightly different state-space (n, delta f(x), lambda_{t-1})
# In this setting, the agent can learn the best policy for OneMax using the 1/5th rule:
# if delta f(x) = f(x_t) - f(x_{t-1}) <= 0: lambda_t = min{(3/2)^1/4 * lambda_{t-1}, n-1}
# otherwise: lambda_t = max{2/3 * lambda_{t-1}, 1}
onell_lbd_onefifth = copy(onell_lbd_theory)
onell_lbd_onefifth["name"] = "lbd_onefifth"
onell_lbd_onefifth["observation_space_type"] = np.float32
onell_lbd_onefifth["observation_space_args"] = [np.array([1, 0, 1]), np.array([np.inf, np.inf, np.inf])]
onell_lbd_onefifth["observation_description"] = "n, delta f(x), lbd_{t-1}"


# Setting 2:
# Name: lbd_p_c
# Description: a more sophisticated setting where we tune lambda, p and c together
# State space: n (int), f(x) (int), delta f(x) (int), lambda_{t-1}, p_{t-1}, c_{t-1}
# action space: lambda (int), p (float), c (float)
onell_lbd_p_c = copy(onell_lbd_theory)
onell_lbd_p_c["name"] = "lbd_p_c"
onell_lbd_p_c["observation_space_type"] = np.float32
onell_lbd_p_c["observation_space_args"] = [np.array([1, 0, 0, 1, 0, 0]), np.array([np.inf, np.inf, np.inf, np.inf, 1, 1])]
onell_lbd_p_c["action_space_args"] = [np.array([1, 0, 0]), np.array([np.inf, 1, 1])]
onell_lbd_p_c["action_description"] = "lbd, p, c"
onell_lbd_p_c["observation_description"] = "n, f(x), delta f(x), lbd_{t-1}, p_{t-1}, c_{t-1}"

# Setting 3:
# Name: lbd1_lbd2_p_c
# Description: a setting where we tune lambda1 (#mutated off-springs), lambda2 (#crossovered off-springs), p and c together
# State space: n (int), f(x) (int), delta f(x) (int), lambda1_{t-1}, lambda2_{t-1}, p_{t-1}, c_{t-1}
# action space: lambda1 (int), lambda2 (int), p (float), c (float)
onell_lbd1_lbd2_p_c = copy(onell_lbd_theory)
onell_lbd1_lbd2_p_c["name"] = "lbd1_lbd2_p_c"
onell_lbd1_lbd2_p_c["observation_space_type"] = np.float32
onell_lbd1_lbd2_p_c["observation_space_args"] = [np.array([1, 0, 0, 1, 1, 0, 0]), np.array([np.inf, np.inf, np.inf, np.inf, np.inf, 1, 1])]
onell_lbd1_lbd2_p_c["action_space_args"] = [np.array([1, 1, 0, 0]), np.array([np.inf, np.inf, 1, 1])]
onell_lbd1_lbd2_p_c["action_description"] = "lbd1, lbd2, p, c"
onell_lbd1_lbd2_p_c["observation_description"] = "n, f(x), delta f(x), lbd1_{t-1}, lbd2_{t-1}, p_{t-1}, c_{t-1}"

def config_to_json(config_name, json_file=None):
"""
Write a config to json file

Parameters
---------
config_name: str
accept values: one of the configs defined above
json_file: str
output .json file name. If None, will be set as <config_name>.json
"""
if json_file is None:
json_file = config_name + ".json"

with open(json_file, 'wt') as f:
bench = AbstractBenchmark()
bench.config = globals()['onell_' + config_name]
bench.save_config(json_file)


def export_all_configs_to_json(output_dir = './'):
"""
Export all configs above to json files
"""
for config_name in ['lbd_theory', 'lbd_onefifth', 'lbd_p_c', 'lbd1_lbd2_p_c']:
config_to_json(config_name, json_file=output_dir + '/' + config_name + '.json')


#export_all_configs_to_json()
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/onell/lbd1_lbd2_p_c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd1_lbd2_p_c", "action_space_class": "Box", "action_space_args": [[1, 1, 0, 0], [Infinity, Infinity, 1.0, 1.0]], "action_description": "lbd1, lbd2, p, c", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.float32'>", "observation_space_args": [[1, 0, 0, 1, 1, 0, 0], [Infinity, Infinity, Infinity, Infinity, Infinity, 1.0, 1.0]], "observation_description": "n, f(x), delta f(x), lbd1_{t-1}, lbd2_{t-1}, p_{t-1}, c_{t-1}", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/onell/lbd_onefifth.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd_onefifth", "action_space_class": "Box", "action_space_args": [[1], [Infinity]], "action_description": "lbd", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.float32'>", "observation_space_args": [[1, 0, 1], [Infinity, Infinity, Infinity]], "observation_description": "n, delta f(x), lbd_{t-1}", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/onell/lbd_p_c.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd_p_c", "action_space_class": "Box", "action_space_args": [[1, 0, 0], [Infinity, 1.0, 1.0]], "action_description": "lbd, p, c", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.float32'>", "observation_space_args": [[1, 0, 0, 1, 0, 0], [Infinity, Infinity, Infinity, Infinity, 1.0, 1.0]], "observation_description": "n, f(x), delta f(x), lbd_{t-1}, p_{t-1}, c_{t-1}", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
1 change: 1 addition & 0 deletions dacbench/additional_configs/onell/onell/lbd_theory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name": "lbd_theory", "action_space_class": "Box", "action_space_args": [[1], [Infinity]], "action_description": "lbd", "observation_space_class": "Box", "observation_space_type": "<class 'numpy.int32'>", "observation_space_args": [[1, 0], [Infinity, Infinity]], "observation_description": "n, f(x)", "reward_range": [-Infinity, Infinity], "cutoff": 1000000000.0, "include_xprime": true, "count_different_inds_only": true, "seed": 0, "problem": "OneMax", "instance_set_path": "../instance_sets/onell/onemax_2000.csv", "benchmark_info": {"identifier": "onell", "name": "OneLL-GA benchmark", "reward": "", "state_description": [""]}, "wrappers": []}
2 changes: 2 additions & 0 deletions dacbench/benchmarks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from dacbench.benchmarks.cma_benchmark import CMAESBenchmark
from dacbench.benchmarks.modea_benchmark import ModeaBenchmark
from dacbench.benchmarks.sgd_benchmark import SGDBenchmark
from dacbench.benchmarks.modcma_benchmark import ModCMABenchmark

__all__ = [
"LubyBenchmark",
Expand All @@ -12,4 +13,5 @@
"CMAESBenchmark",
"ModeaBenchmark",
"SGDBenchmark",
"ModCMABenchmark"
]
Loading