protected static IEnumerable <Node> generateLeafNodes(NodeClass c, NodeTypeFrequencyProfile profile) { Node n = null; switch (c) { case NodeClass.directive: n = new directiveTerminal(); yield return(n); break; case NodeClass.numeric: for (int i = 0; i < 2; i++) { n = new NumericConstant(i); yield return(n); } break; case NodeClass.boolean: yield return(new BoolConstant(false)); yield return(new BoolConstant(true)); break; default: break; } }
public RandomSearch(TrainingSamplesGenerator gen, int maxDepth, NodeTypeFrequencyProfile profile, int batchSize = 128) : base(gen) { this.profile = profile; this.maxDepth = maxDepth; this.batchSize = batchSize; }
public RandomMutationSearch(TrainingSamplesGenerator generator, int mutationsInEachStep, NodeTypeFrequencyProfile profile) : base(generator) { this.mutationsInStep = mutationsInEachStep; this.profile = profile; this.mutator = new PointMutation(profile, 3); this.mutatedPrograms = new List <EvaluatedEntity <SolutionProgram> >(); }
protected static IEnumerable <Node> generateRootNodes(NodeClass c, NodeTypeFrequencyProfile profile) { foreach (var item in EnumUtils.getTypesByClass(c)) { Node n = SearchMethodsSupport.createPrototypeNode(item); if (n.successors.count <= 0) { continue; } yield return(n); } }
/// <summary> /// Creates a tree of fully instantiated nodes with given depth. Nodes at the leaf level will be default-value-nodes. /// </summary> /// <param name="cl"></param> /// <param name="profile"></param> /// <param name="depth"></param> /// <returns></returns> public static Node createRandomTree(NodeClass cl, NodeTypeFrequencyProfile profile, int depth, NodeCreationConstrains contrains = null) { if (depth == 0) { return(createDefaultNode(cl, contrains)); } Node root = createRandomNode(cl, profile, contrains); foreach (var slot in root.successors.getSlots()) { slot.setNodeConnectedToSlot(createRandomTree(slot.argumentClass, profile, depth - 1, contrains)); } return(root); }
//TODO //dodelat spravne odsazovani u metody tostring u Nodu //do profilu (nebo jinam) dat pravidla co kde muze a nesmi byt. napr. v tele forcyklu se musi vyskytovat ridici promenna, u operatoru nesmi byt jen konstanty //to se da udelat tak, ze prvni argument operatoru nesmi byt konstanta (a to by se propagovalo hloubs) //v celem programu se musi prirazovat do vysledku a cist vstupy atd.. //pri generovani podstromu by hloubka nemela byt pouze fixni, ale mely by tam byt vsechny stromy s hloubkou mensi rovnou danemu limitu //profil nebude uniformni, ale podmineny, tzn. nebude dana "globalni pravdepodobnost vyskytu typu uzlu", ale "pravdepodobnost vyskytu typu uzlu v zavislosti na typu rodice" //To by melo omezit vyskyt ReadVar -> ReadVar a podobne. -- DONE //pri hodnoceni uspesnosti programu je nutne brat v uvahu nejen vysledek, ale i neco dalsiho. Napr. hodnoty vnitrnich promennych na konci, posloupnost hodnot vnitrnich promennych v prubehu vypoctu, nebo neco podobneho //obecne by to mely byt kriteria, ktera bud zada uzivatel, nebo se najdou automaticky (pomoci "korelaci" vstupu s pozadovanymi vystupy, resp. kriterium je "uzitecne" pokud pro vsechny x: korelace(krit(x), target(x)) je velka. //Pricemz "korelace" je spis v Kolmogorovskem smyslu - tzn. {a_i} a {b_i} maji velkou korelaci pokud program, ktery pro vsechny "i" prevadi a_i na b_i je kratky) //prohledavani prostoru programu: //A* s heuristikou, kde heuristika je "velikost programu, ktery prevadi vystup toho, co mame ted, na pozadovany vystup" (pomoci aproximace kolmogorovske slozitosti) //MCTS - podobne. program se bude stavet pomoci MCTS, heuristika bude ohodnoceni, pravdepodobne pouzit AMAF, v listech delat samplovani (vyhodnoti se vzdycky jen na malem mnozstvi samplu pri kazde navsteve) /// <summary> /// Enumerates all trees of given depth /// </summary> /// <param name="args"></param> static void Main5(string[] args) { NodeTypeFrequencyProfile p = new NodeTypeFrequencyProfile(); for (int depth = 3; depth < 5; depth++) { //Console.WriteLine("number of graphs of depth " + depth + ": " + TreeIterator.enumerateAllTrees(NodeClass.directive, depth, p).Count()); //continue; foreach (var tree in TreeIterator.enumerateAllTrees(NodeClass.directive, depth, p)) { new GraphVisualizer().visualizeDialog(ProgramTreeDrawer.createGraph(new SolutionProgram((DirectiveNode)(tree)))); } } }
public static NodeTypeFrequencyProfile createProfile(IEnumerable <Node> allNodes, bool atLeastOneOfEach) { NodeTypeFrequencyProfile result = new NodeTypeFrequencyProfile(); foreach (var node in allNodes) { result.increaseCount(node.type, 1); } if (atLeastOneOfEach) { result.addOneOfEach(); } result.sortTypeByFrequencies(); return(result); }
/// <summary> /// Creates a frequency profile of occurence of nodes of specific types in given set of programs. If atLeastOneOfEach is set to true, frequency of all nodes will initially be set to one, which leads to non-zero probability of generating every type of node, /// even if it is never encountered in any of given programs. If it is set to false, initial frequencies will be set to zero and nodetypes that were never encountered in samples will never be generated. /// </summary> /// <param name="programs"></param> /// <param name="atLeastOneOfEach"></param> /// <returns></returns> public static NodeTypeFrequencyProfile createProfile(List <SolutionProgram> programs, bool atLeastOneOfEach) { NodeTypeFrequencyProfile result = new NodeTypeFrequencyProfile(); foreach (var program in programs) { foreach (var node in program.getAllNodes()) { result.increaseCount(node.type, 1); } } if (atLeastOneOfEach) { result.addOneOfEach(); } result.sortTypeByFrequencies(); return(result); }
/// <summary> /// To test the Clone() method /// </summary> /// <param name="args"></param> static void Main3(string[] args) { NodeTypeFrequencyProfile p = NodeTypeFrequencyProfile.createProfile(new List <SolutionProgram> { getProgram0(), getProgram1(), getProgram2() }, true); for (int i = 0; i < 50; i++) { Console.WriteLine("New random program:"); SolutionProgram pr = new SolutionProgram((DirectiveNode)SearchMethodsSupport.createRandomTree(NodeClass.directive, p, 10)); Console.WriteLine(pr.ToString()); new GraphVisualizer().visualizeDialog(ProgramTreeDrawer.createGraph(pr)); Console.WriteLine(); Console.WriteLine("CLONE:"); SolutionProgram clon = (SolutionProgram)pr.Clone(); Console.WriteLine(clon.ToString()); new GraphVisualizer().visualizeDialog(ProgramTreeDrawer.createGraph(clon)); Console.WriteLine(); } }
public static NodeTypeRelativizedFrequencyProfile createProfile(List <SolutionProgram> programs) { int minPrograms = 100; int repeat = programs.Count < minPrograms ? minPrograms - programs.Count : 1; NodeTypeRelativizedFrequencyProfile result = new NodeTypeRelativizedFrequencyProfile(); result.simpleProfile = createProfile(programs, atLeastOneOfEach: true); foreach (var program in programs) { foreach (var node in program.getAllNodes()) { if (!result.relativizedProfiles.ContainsKey(node.type)) { NodeTypeFrequencyProfile p = NodeTypeFrequencyProfile.createProfile(enumarateAllNodesThatAreSuccessorsOfType(node.type, programs, repeat), atLeastOneOfEach: true); result.relativizedProfiles.Add(node.type, p); } } } return(result); }
public static IEnumerable <Node> enumerateAllTrees(NodeClass cl, int depth, NodeTypeFrequencyProfile profile) { if (depth <= 0) { yield break; } if (depth == 1) { foreach (var item in generateLeafNodes(cl, profile)) { yield return(item); } } else { foreach (var root in generateRootNodes(cl, profile)) { foreach (var tree in generateSubtrees(root, 0, depth - 1, profile)) { yield return(tree); } } } }
public PointMutation(NodeTypeFrequencyProfile profile, int treeDepth) { this.profile = profile; this.treeDepth = treeDepth; }
protected static IEnumerable <Node> generateSubtrees(Node root, int succIndex, int maxDepth, NodeTypeFrequencyProfile profile) { if (succIndex >= root.successors.count) { yield return(root.createDeepCopy()); } else { Slot s = root.successors.GetSlot(succIndex); if (maxDepth == 1) { foreach (var succ in generateLeafNodes(s.argumentClass, profile)) { s.setNodeConnectedToSlot(succ); foreach (var result in generateSubtrees(root, succIndex + 1, maxDepth, profile)) { yield return(result); } } } else { foreach (var succ in generateRootNodes(s.argumentClass, profile)) { for (int subtreeDepth = 1; subtreeDepth < maxDepth; subtreeDepth++) { foreach (var subtree in generateSubtrees(succ, 0, subtreeDepth, profile)) { s.setNodeConnectedToSlot(succ); foreach (var result in generateSubtrees(root, succIndex + 1, maxDepth, profile)) { yield return(result); } } } } } } }
/// <summary> /// Creates a new fully initialized node whose type is selected randomly based on distribution in given NodeTypeFrequencyProfile object. Node that require value to be set (like numeric constants) will receive a random number between 0 and 10 as their value. /// If the node requires successors to be specified, such successors will be created and default-value-node will be used. /// </summary> /// <param name="cl"></param> /// <param name="profile"></param> /// <returns></returns> public static Node createRandomNode(NodeClass cl, NodeTypeFrequencyProfile profile, NodeCreationConstrains constrains = null) { NodeType t = profile.getRandomNodeType(cl, constrains); return(createRandomNode(t, constrains)); }