PonyGE / PonyGE2

PonyGE2: grammatical evolution and variants in Python
GNU General Public License v3.0
155 stars 92 forks source link

load_state not working with functions in custom module #156

Open MihaiBabiac opened 2 years ago

MihaiBabiac commented 2 years ago

When using custom functions for mutation, initialisation, etc. that are stored in a separate directory, PonyGE2 fails to load them from a saved state.

For example, the state saved by the following call can't be loaded because the mutation function custom.mutation.custom_mutation_per_ind is stored in the state as just "custom_mutation_per_ind", ignoring the rest of the path.

python ponyge.py --grammar_file ../grammars/custom_grammar.pybnf --fitness_function custom_fitness --mutation custom.mutation.custom_mutation_per_ind --save_state

My fix for this is below:

--- a/PonyGE2/src/utilities/algorithm/initialise_run.py
+++ b/PonyGE2/src/utilities/algorithm/initialise_run.py
@@ -237,7 +237,11 @@ def get_fit_func_imports():
         attr_name = split_name[-1]

         # Get module name.
-        module_name = ".".join(["fitness", params[op]])
+        if not params[op].startswith("fitness."):
+            module_name = ".".join(["fitness", params[op]])
+        else:
+            # Special case when loading from a saved state
+            module_name = ".".join(split_name[:-1])

         # Import module and attribute and save.
         params[op] = return_attr_from_module(module_name, attr_name)
--- a/PonyGE2/src/utilities/algorithm/state.py
+++ b/PonyGE2/src/utilities/algorithm/state.py
@@ -142,8 +154,12 @@ def check_name(obj):
     :param obj: An object for which we want to find the name.
     :return: The name of the object
     """
+    try:
+        prefix = obj.__module__ + "."
+    except AttributeError:
+        prefix = ""

     try:
-        return obj.__name__
+        return prefix + obj.__name__
     except AttributeError:
-        return obj.__class__.__name__
+        return prefix + obj.__class__.__name__