Skip to content

Commit

Permalink
Make the JSON encoder/decoder private
Browse files Browse the repository at this point in the history
  • Loading branch information
dhadka committed Sep 12, 2024
1 parent 4150763 commit 80254d7
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 7 deletions.
1 change: 1 addition & 0 deletions platypus/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from .errors import PlatypusError

class _PlatypusConfig:
"""Global configuration options for Platypus."""

def __init__(self):
super().__init__()
Expand Down
29 changes: 28 additions & 1 deletion platypus/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ class Variator(metaclass=ABCMeta):
"""Abstract class for variation operators (crossover and mutation).
Variation operators must not modify the parents! Instead, create a copy
of the parents, set :code:`evaluated` to :code:False`, and modify the copy::
of the parents, set :code:`evaluated` to :code:`False`, and make any
modifications on the copy::
child = copy.deepcopy(parent)
child.evaluated = False
Expand Down Expand Up @@ -1057,6 +1058,28 @@ def __iter__(self):
return iter(self._contents)

class AdaptiveGridArchive(Archive):
"""A bounded archive using density to truncate solutions.
The objective space is partitioned into a grid containing
:code:`math.pow(divisions, nobjs)` cells. Please note that this can
quickly result in a large internal array or an integer overflow as either
:code:`divisions` or :code:`nobjs` grows.
The density of each cell is measured by counting the number of solutions
within the cell. When the archive exceeds the desired capacity, a solution
is removed from the densest cell(s).
Parameters
----------
capacity : int
The maximum capacity of this archive.
nobjs : int
The number of objectives.
divisions : int
The number of divisions in objective space
dominance : Dominance
The dominance criteria (default is Pareto dominance).
"""

def __init__(self, capacity, nobjs, divisions, dominance=ParetoDominance()):
super().__init__(dominance)
Expand Down Expand Up @@ -1119,6 +1142,7 @@ def remove(self, solution):
return removed

def adapt_grid(self):
"""Adapts the grid by updating the bounds and density."""
self.minimum = [POSITIVE_INFINITY]*self.nobjs
self.maximum = [-POSITIVE_INFINITY]*self.nobjs
self.density = [0.0]*(self.divisions**self.nobjs)
Expand All @@ -1132,6 +1156,7 @@ def adapt_grid(self):
self.density[self.find_index(solution)] += 1

def find_index(self, solution):
"""Returns the grid cell index of the given solution."""
index = 0

for i in range(self.nobjs):
Expand All @@ -1155,6 +1180,7 @@ def find_index(self, solution):
return index

def find_densest(self):
"""Finds the grid cell index with the highest density."""
index = -1
value = -1

Expand All @@ -1169,6 +1195,7 @@ def find_densest(self):
return index

def pick_from_densest(self):
"""Picks a solution from the densest grid cell(s)."""
solution = None
value = -1

Expand Down
4 changes: 2 additions & 2 deletions platypus/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ class Job(metaclass=ABCMeta):
"""Abstract class for implementing a distributable job.
The job should capture any inputs required by :meth:`run` along with any
outputs produced by the job.
outputs produced by the job as attributes.
Also be aware that the specific :class:`Evaluator` used to run the jobs
might mandate additional requirements. For instance, evaluators that
distributed jobs across processes or machines typically need to
distribute jobs across processes or machines typically need to
serialize or pickle Python objects to transmit them over a network.
"""

Expand Down
8 changes: 4 additions & 4 deletions platypus/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def save_objectives(file, solutions):
f.write(" ".join(map(str, solution.objectives)))
f.write("\n")

class PlatypusJSONEncoder(json.JSONEncoder):
class _PlatypusJSONEncoder(json.JSONEncoder):

def default(self, obj):
if isinstance(obj, (Archive, FixedLengthArray)):
Expand All @@ -88,7 +88,7 @@ def default(self, obj):
"constraints": obj.constraints}
return super().default(obj)

class PlatypusJSONDecoder(json.JSONDecoder):
class _PlatypusJSONDecoder(json.JSONDecoder):

def __init__(self, problem=None, *args, **kwargs):
super().__init__(object_hook=self.object_hook, *args, **kwargs)
Expand Down Expand Up @@ -140,7 +140,7 @@ def dump(obj, fp, indent=None):
indent:
Controls the formatting of the JSON fle, see :meth:`json.dump`.
"""
json.dump(obj, fp, cls=PlatypusJSONEncoder, indent=indent)
json.dump(obj, fp, cls=_PlatypusJSONEncoder, indent=indent)

def load(fp, problem=None):
"""Loads the JSON data.
Expand All @@ -152,7 +152,7 @@ def load(fp, problem=None):
problem : Problem, optional
Optional problem definition. If not set, a placeholder is used.
"""
return json.load(fp, cls=PlatypusJSONDecoder, problem=problem)
return json.load(fp, cls=_PlatypusJSONDecoder, problem=problem)

def save_json(file, solutions, indent=None):
"""Converts the solutions to JSON and saves to a file.
Expand Down

0 comments on commit 80254d7

Please sign in to comment.