def changeRandomModule(self,pString): pString = ParametricString.copyFrom(pString) available_letters = [m.letter for m in self.template_modules_library.getTemplateModules()] # Choose what module we want to change modules = pString.getActualModules() modules = list(filter(lambda m: m.letter in available_letters,modules)) index = self.rnd.randint(0,len(modules)-1) module_to_change = modules[index] #print("We will change module at : " + str(index) + " " + str(module_to_change)) # Choose what we will change it to, avoid replacing with the same letter new_module = self.generateRandomModule(notUsingModules = [module_to_change]) #print("Changed to " + str(new_module)) # If parameterized, we make sure that the parameter value remains the same, if possible if self.parameterized: for i in range(len(new_module.params)): if i < len(module_to_change.params): new_module.params[i] = module_to_change.params[i] #print("From string " + str(string) + " we change module " + str(string[index]) + " at index " + str(index) + " to a new module " + new_module) pString.modulesList[pString.modulesList.index(module_to_change)] = new_module #print("Result: " + string) return pString
def setAxiomFromString(self,textString): """ @param textString: Initial string to parse @type textString: str """ newPString = ParametricString.fromTextString(textString) newPString.setGlobals(self.globalDefines) self.axiom = newPString
def removeModule(self,module,input_pstring): #print(module) #print(pString) output_pstring = ParametricString.copyFrom(input_pstring) if module in input_pstring.modulesList: index = input_pstring.index(module) removeBrackets = self.checkBracketsRemoval(index,output_pstring) del output_pstring.modulesList[index] if removeBrackets: self.performBracketsRemoval(index,output_pstring) return output_pstring
def removeRandomModule(self,pString): pString = ParametricString.copyFrom(pString) available_letters = [m.letter for m in self.template_modules_library.getTemplateModules()] while True: index = self.rnd.randint(0,len(pString)-1) if not pString[index].isBracket() and pString[index].letter in available_letters: break # We also remove the brackets if no other module is there removeBrackets = self.checkBracketsRemoval(index, pString) del pString.modulesList[index] if removeBrackets: self.performBracketsRemoval(index, pString) #TODO: Do something if we completely remove this production return pString
def addRandomModule(self,pString): """ Add a random Module to a ParametricString, chosen from the available ones. This may select an unused Module too. #TODO: this is actually an "insertInRandomModule" """ #print("Current pString: " + str(pString)) pString = ParametricString.copyFrom(pString) new_module = self.generateWeightedRandomModule()#parametric=True) index = self.rnd.randint(0,len(pString)) # Max is len(pString) so that we can also insert at the end #print("From string " + str(pString) + " we add at index " + str(index) + " a new Module " + str(new_module)) pString.modulesList.insert(index,new_module) #print("Result: " + str(pString)) if new_module.letter not in self.currentlyUsedLetters: self.currentlyUsedLetters.append(new_module.letter) return pString
def iterate_loop(self, N): if N is None: N = self.niterations currentParametricString = ParametricString.copyFrom(self.axiom) # We create a copy so to not modify the axiom #self.axiom.evaluateDefines() #print(self) #print(self.globalDefines) for i in range(N): if self.verbose: print("\nStep " + str(i+1)) currentParametricString.resetConversions() # All productions are applied in parallel for prod in self.productions: if self.verbose: print("Rule: " + str(prod)) result = prod.check(currentParametricString,self.rnd) #print("Rule evaluates: " + str(result)) if result: currentParametricString = prod.convert(currentParametricString) if self.verbose: print("String at step " + str(i+1) + " is " + str(currentParametricString)) ParametricProduction.resetStochasticState() currentParametricString.evaluateDefines() return currentParametricString
def parseSuccessorString(self,string): successor = ParametricString() successor.setGlobals(self.globalDefines) successor.parseString(string) return successor
def parsePredecessorString(self,string): predecessorPString = ParametricString() predecessorPString.setGlobals(self.globalDefines) predecessorPString.parseString(string) # TODO: Maybe this predecessor should be treated as a 1-module string for consistency, instead of a module? assert len(predecessorPString) == 1, 'The predecessor must contain only one module!' return predecessorPString[0] # Only one
def __init__(self): ParametricString.__init__(self)
print("\nChange predecessor: parametric") pm = ParametricModule.fromTextString("A(x)") pp.setPredecessorModule(pm) print(pp) print(pm.letter) print("\nChange condition: probability") pp.setConditionFromString("0.8") print(pp) print("\nChange condition: parametric") pp.setConditionFromString("x>0.9") print(pp) print("\nChange successor: parametric") ps = ParametricString.fromTextString('F(x)A(p)') pp.setSuccessorPstring(ps) print(pp) import random rnd = random.Random() print("\nCheck condition") ps = ParametricString.fromTextString("A(1)") print("Input: " + str(ps)) result = pp.check(ps, rnd) print("Result: " + str(result)) print("\nConvert and evaluate (also globals)") print("Input: " + str(ps)) ps = pp.convert(ps) print("Result: " + str(ps))
def insertModuleIntoPstringRandomly(self,new_module,pString): pString = ParametricString.copyFrom(pString) index = self.rnd.randint(0,len(pString)) # Max is len(pString) so that we can also insert at the end pString.modulesList.insert(index,new_module) if new_module.letter not in self.currentlyUsedLetters: self.currentlyUsedLetters.append(new_module.letter) return pString
def appendModuleToPstring(self,new_module,pString): pString = ParametricString.copyFrom(pString) pString.modulesList.append(new_module) if new_module.letter not in self.currentlyUsedLetters: self.currentlyUsedLetters.append(new_module.letter) return pString
def generateEmptyParametricString(self): pstring = ParametricString() pstring.setGlobals(self.lsystem.globalDefines) return pstring
def generateRandomParametricString(self, minLength = MIN_GENERATED_STRING_LENGTH, maxLength = MAX_GENERATED_STRING_LENGTH, predecessor_module = None): """ Generates a random string composed of ParametricModules. May also randomly open and close branches. May also randomly add new defines. Forces the string's validity. If a predecessor_module is passed, its parameter variables (x,y) need to appear in the generated string We add them to the current generated string at the end. """ if self.branchProbability > 0.0: openBranches = 0 n_modules = self.rnd.randint(minLength,maxLength) pstring = ParametricString() pstring.setGlobals(self.lsystem.globalDefines) for i in range(n_modules): # We add N modules # Generate the module new_module = self.generateWeightedRandomModule()#parametric=True) # Randomly open branches (NOT: only if the module is a new rotation, otherwise it doesn't make sense) if self.branchProbability > 0.0: if openBranches > 0 and self.rnd.random() < self.branchCloseProbability: pstring.appendCloseBranch() openBranches -= 1 if self.rnd.random() < self.branchProbability: #new_module.isOrientation() and pstring.appendOpenBranch() openBranches += 1 # Append the module pstring.appendModule(new_module) # Close the remaining branches if self.branchProbability > 0.0: for i in range(openBranches): pstring.appendCloseBranch() # Change some of the parameters to the predecessor module's variable parameters if self.parameterized: print("PRED: " + str(predecessor_module)) if predecessor_module is not None: potential_changed_modules = pstring.modulesList potential_changed_modules = list(filter(lambda p: not p.isBracket(), pstring.modulesList)) #print "Potential changed modules: " #for m in potential_changed_modules: print m # Each predecessor parameter is copied once, if possible for param in predecessor_module.params: chosen_module = self.getRandomItemFromList(potential_changed_modules) #if len(chosen_module.params) > 0: index = self.rnd.randint(0,len(chosen_module.params)-1) chosen_module.params[index] = param return pstring