Source code for HyperGP.libs.representation.GEP

import copy

from HyperGP.base.prog_basic import Program
from ..states import ProgBuildStates
from ..utils import HalfAndHalf


[docs] class GEPIndv(Program):
[docs] def __init__(self, states=None, encode=None, **kwargs): if states is not None: if 'module_states' not in states and 'states' not in states: super().__init__(state=states, **kwargs) else: super().__init__(**states, **kwargs) else: super().__init__(state=None, module_states=None, **kwargs) if encode is not None: self.encode = encode
"""""" def buildProgram(self, cond: ProgBuildStates, method, node_states=None): encode = method(cond, node_states) # self.stateRegister(encode=root) self.encode = encode def __len__(self): return len(self.encode) def list(self, parent=False, childs=False): """transform the gep-encode to the preorder list""" pc_list = [] '''child list''' c_list = [] # child_idx = [1] # child_num = self.encode[0].arity # def add_idx(i): # child_idx[0] += self.encode[i].arity # return child_idx[0] # child_idx_list = [1] + [add_idx(i) for i, node in enumerate(self.encode) if i > 0] # c_list = [[child_idx_list[i] + z for z in range(self.encode[i].arity)] if self.encode[i].arity > 0 else [] for i, node in enumerate(self.encode)] child_idx = 1 child_num = self.encode[0].arity for i, node in enumerate(self.encode): if child_num > 0: c_list.append([child_idx + z for z in range(child_num)]) else: c_list.append([]) child_idx += child_num child_num = self.encode[i + 1 if i + 1 < len(self.encode) else i].arity if childs: pc_list.append(c_list) '''parent list''' if parent: p_list = [] def set_parent(child_list, p_idx): for node in enumerate(child_list): p_list[node] = [p_idx] for i, nodes in enumerate(c_list): if len(nodes) > 0: set_parent(nodes, i) pc_list.append(p_list) assert 0==1, "the implementation should be finished first" '''preorder list''' pre_list = [] queue_obj = [] cur_idx = 0 queue_obj.append(cur_idx) while len(queue_obj) > 0: c_idx = queue_obj.pop() if c_idx >= len(self.encode): assert 0==1, "{S}, {S2}, {S1}".format(S=self.__str__(), S2=str(self), S1=[str(s) for s in self.encode]) pre_list.append(self.encode[c_idx]) for node in range(len(c_list[c_idx]) - 1 , -1, -1): queue_obj.append(c_list[c_idx][node]) if not parent and not childs: # print('pre_list: ', pre_list) return pre_list return pc_list def slice(self, begin=None, end=None): if begin is None: begin = 0 end = begin + 1 total = self[begin].arity while total > 0: total += self[end].arity - 1 end += 1 return slice(begin, end) def __getitem__(self, item): return self.encode[item] def __setitem__(self, key, value): if isinstance(key, slice): if key.start >= len(self): raise IndexError("Invalid slice object (try to assign a %s" " in a tree of size %d). Even if this is allowed by the" " list object slice setter, this should not be done in" " the PrimitiveTree context, as this may lead to an" " unpredictable behavior for searchSubtree or evaluate." % (key, len(self))) total = value[0].arity for node in value[1:]: total += node.arity - 1 if total != 0: raise ValueError("Invalid slice assignation : insertion of" " an incomplete subtree is not allowed in PrimitiveTree." " A tree is defined as incomplete when some nodes cannot" " be mapped to any position in the tree, considering the" " primitives' arity. For instance, the tree [sub, 4, 5," " 6] is incomplete if the arity of sub is 2, because it" " would produce an orphan node (the 6).") self.encode.__setitem__(key, value) def copy(self): return copy.deepcopy(self, {}) def __str__(self): def format(node, *args): if node.arity > 0: _args = ", ".join(map("{{{0}}}".format, range(node.arity))) seq = "{name}({args})".format(name=str(node), args=_args) return seq.format(*args) else: return str(node) string = "" stack = [] arity, parent_idx = 0, -1 parent_list = [-1] finish = False if self.encode[0].arity == 0: return str(self.encode[0]) # print("self.encode: ", [str(s) for s in self.encode]) # print("========================") for i, node in enumerate(self.encode): stack.append((i, [])) '''find leave node''' if node.arity == 0 and i != 0: stack[parent_list[i]][-1].append(str(node)) p_id = parent_list[i] while len(stack[p_id][1]) == self.encode[p_id].arity: parent = parent_list[p_id] prim, args = self.encode[p_id], stack[p_id][1] string = format(prim, *args) if parent == -1: finish=True break stack[parent][1].append(string) p_id = parent if finish: break '''record parent''' while arity == 0: parent_idx += 1 if parent_idx > i: print(parent_idx, i, len(self.encode), [str(s) for s in self.encode]) assert 0==1 break arity = self.encode[parent_idx].arity parent_list.append(parent_idx) arity -= 1 assert len(stack[0][1]) == self.encode[0].arity, "can not transform the ind into str..." return string