def play_motif(self): """ Find motif with the best evaluation from the agents vocabulary. Create a variation of the motif and see if it would be better. If the variation is better, memorize it and return it. Estimate if playing the motif would increase the agent's confidence level. If the motif is estimated to not increase the confidence level enough, the agent rests instead i.e. produces a motif that is all rests. With probability pr_of_contrast the agent plays something contrary to the context or random. :return: Motif with best evaluation. :rtype: Motif """ motif_to_play = None best_evaluation = 0.0 # Find motif with best evaluation from vocabulary for motif in self._vocabulary: evaluation = self.evaluate(Artifact(self, obj=motif, domain='music')) if evaluation > best_evaluation: motif_to_play = motif best_evaluation = evaluation # Get a random variation of the motif and see if it would be better than the original. variation = Motif.get_random_variation(motif_to_play) # If the variation is at least as good as the found best motif use it instead and memorize it. evaluation_of_variation = self.evaluate(Artifact(self, obj=variation, domain='music')) if evaluation_of_variation >= best_evaluation: motif_to_play = variation best_evaluation = evaluation_of_variation self._vocabulary.memorize(motif_to_play) # Estimate what the future confidence level would be if the agent played the motif estimate_of_future_confidence = (self._sum_of_evaluations + best_evaluation) / (self._steps_acted + 1) if estimate_of_future_confidence <= self._confidence * (1 + self._confidence_threshold): # If playing the motif would not increase confidence enough, rest. motif_to_play = Motif.get_rest(self._motif_length) # With probability of pr_of_contrast the agent decides to play something contrasting. play_contrasting = random.random() if play_contrasting <= self._pr_of_contrast: if not motif_to_play.is_all_rests(): motif_to_play = self._vocabulary.find_least_similar(motif_to_play) else: # If there is no motif to contrast against, choose a random motif. motif_to_play = self._vocabulary.get_random_motif() # Keep track of the last motif played self._last_motif = motif_to_play # Transpose the best_motif based on key estimates. # The motifs are handled in a key invariant way so memorizing the transposed motif is unnecessary. return Motif.transpose_to_key_of_context(motif_to_play, self._memory_of_situation)
def create(self, x, y, choose_cell): '''Create a maze with the growing tree algorithm. ''' maze = gt.create(x, y, choose_cell) start = gt.room2xy(gt.random_room(maze)) goal = gt.room2xy(gt.random_room(maze)) art = Artifact(self, (maze, start, goal)) return art
def listen_to_others(self, musical_context, step): """ Update the agent's knowledge of the musical situation and evaluate how well the last played motif worked out. Learn surprising motifs from the musical context. Update the confidence level of the agent. :param musical_context: Motifs recently played in the environment. :type musical_context: list :param step: The step of the simulation. :type step: int """ # Update the agent's memory of the situation by choosing random motifs from the musical_context and # putting them into the memory. num_motifs = min(self.memory_capacity, len(musical_context)) perceived_motifs = random.sample(musical_context, num_motifs) for motif in perceived_motifs: # The perceived motifs replace oldest motifs in the memory. self._memory_of_situation.memorize(motif, step=step, replace_most_similar=False) # Find most surprising motif from the motifs perceived from environment most_surprising = None max_surprise = 0.0 for motif in perceived_motifs: surprise = self.surprisingness(motif) if surprise > max_surprise: max_surprise = surprise most_surprising = motif # Evaluate how good the last own motif was. evaluation = self.evaluate(Artifact(self, obj=self._last_motif, domain='music')) # Check that an at all surprising motif was found and memorize the most surprising motif # as a random variation if it is evaluated better than own last motif. if most_surprising: if self.evaluate(Artifact(self, obj=most_surprising, domain='music')) > evaluation: self._vocabulary.memorize(Motif.get_random_variation(most_surprising)) # Update the confidence level of the agent. self._sum_of_evaluations += evaluation self._confidence = self._sum_of_evaluations / self._steps_acted # If the agents last motif was a rest, the agent did not play anything # and the confidence level decreases even more. if self._last_motif.is_all_rests(): self._confidence *= self._confidence_decline_factor
def invent(self, n): '''Invent a new artifact by generating **n** artifacts and selecting the best one. Selection is done based on :meth:`evaluate`. :param int n: The number of alternative artifacts generated :returns: :class:`~creamas.core.artifact.Artifact`, the best artifact based on :meth:`evaluate` ''' g = self.generate() best_artifact = Artifact(self, g) best_eval, _ = self.evaluate(best_artifact) for _ in range(n - 1): g = self.generate() artifact = Artifact(self, g) evl, _ = self.evaluate(artifact) if evl > best_eval: best_artifact = artifact best_eval = evl best_artifact.add_eval(self, best_eval) return best_artifact, best_eval
def agents_listen_and_evaluate(self, age): """ Agents listen to what has been played in the environment and evaluate their own performance in regard to that. :param age: The step of the simulation. :type age: int """ latest_motifs = self.get_latest_motifs(age) for agent in self.get_agents(address=False): agent.listen_to_others(latest_motifs, age) motif = Artifact(agent, self._parts[agent.name][age - 1], domain='music') agent.evaluate(motif)
def generate(self): """ The HaikuAgent generates a new haiku, drawing on the metaphors in its memory. This includes three steps. * pick a topic noun from a random metaphor in memory * compile a list of nouns and adjectives linked to the topic by searching the metaphor memory * generate three lines of text with the appropriate syllable counts by picking from the filler words, nouns, and adjectives :return: a new :class:'Haiku' """ known_topics = self.memory.metaphor_lookup.keys() if len(known_topics) == 0: return None topic = random.choice(list(known_topics)) nouns, adjectives = self.get_applicable(topic) line_1 = self.write_line(5, nouns, adjectives) line_2 = self.write_line(7, nouns, adjectives) line_3 = self.write_line(5, nouns, adjectives) return Artifact(self, Haiku(topic, line_1, line_2, line_3, max(len(nouns), len(adjectives))), domain=Haiku)
def generate(self): """ Generate a new metaphor by a very simple method: * shuffle the lists of nouns and adjectives * repeatedly pick a noun, then pick another noun, then check if they have any adjectives in common * if an adjective is found in common, with probability 0.5 create a metaphor using these two nouns and that adjective. With probability 0.5 continue searching. * if no adjective in common is found, pick a new noun (without replacement) :return: an Artifact with the Metaphor as its object and :class:'Metaphor' as its domain """ random.shuffle(self.nouns) for noun_1 in self.nouns: for noun_2 in self.nouns: if noun_1.word != noun_2.word: for adj in noun_1.get_adjectives(): if adj.word in [ adj2.word for adj2 in noun_2.get_adjectives() ]: if random.randint(0, 1) == 1: return Artifact(self, Metaphor(noun_1, noun_2, adj), domain=Metaphor) return None