def __add_generator(self, cases, config): # select one case to take care of index = random.randrange(len(cases)) feature_generator = cases[index][0] bond = cases[index][1] print 'selected feature generator', cases[index][0].get_name() print 'path', cases[index][0].get_features() print 'bond value', cases[index][1].get_value() # Get labels by bond value/modality #labels = self.__ontology.get_equivalent_labels(g.get_name()); labels = self.__ontology.get_labels_per_modality(bond.get_value()) print 'labels', labels # Select label from the list of possible labels index = random.randrange(len(labels)) label = labels[index] print 'selected label', label cost = 0 time = feature_generator.get_time() level = self.__ontology.get_level(label) modalities = self.__ontology.get_modalities(label) bond_structure = self.__ontology.get_bond_structure(label) # name,level,modality,type,cost,time new_generator = MyGenerator(label, level, modalities, 'ontological', cost, time) # set feature location associated to the new candidate new_generator.set_rlocation(feature_generator.get_rlocation()) # define the bond structure of the generator here new_generator.set_bond_structure(bond_structure) config.add_generator(new_generator) # make changes to the connection of the new configuration given the newly added generator self.__place_support_bonds(feature_generator, new_generator, config) self.__place_ontological_bonds(new_generator, config) return config
def propose(self, config, with_temporal_bonds=False, selection_type='level', feature_thresh=0.5): ontological_generators = config.get_ontological_generators() if not ontological_generators: return config # First, select an ontological generator to be replaced in the configuration g_r = None level = 4 while level == 4: g_r_index = self.sample('uniform', ontological_generators) g_r = ontological_generators[g_r_index] level = g_r.get_level() g_r_inbonds = g_r.get_inbonds() unconnected_feature_generators = [] # Second, find the feature generators that explain such ontological generator cost = 0 time = g_r.get_time() for inbond in g_r_inbonds: print 'inbond connector: ', inbond.get_value( ), inbond.get_connector() if inbond.get_connector() != None: g = config.get_generator_by(inbond.get_connector(), 'id') if g.get_type() == 'feature': unconnected_feature_generators.append(g) print 'unconnected features: ', repr(unconnected_feature_generators) # print configuration information # config.print_info() # for when feature generator close their inbonds with outbonds of ontological generators if not unconnected_feature_generators: g_r_outbonds = g_r.get_outbonds() for outbond in g_r_outbonds: if outbond.get_connector() != None: g = config.get_generator_by(outbond.get_connector()) if g.get_type() == 'feature': unconnected_feature_generators.append(g) print 'REPLACE ', g_r.get_name() labels = None if selection_type == 'level': labels = self.__ontology.get_same_level_labels(g_r.get_name()) else: # if by modality labels = self.__ontology.get_equivalent_labels(g_r.get_name()) # print 'candidates for replacement: ',labels # select candidates uniformly random k = self.__k if self.__k <= len(labels) else max(self.__k, len(labels)) candidates = random.sample(labels, k) candidate_configs = [] candidate_generators = [] for i in range(len(candidates)): # collect all data to create a generator label_name = candidates[i] level = self.__ontology.get_level(label_name) modalities = self.__ontology.get_modalities(label_name) bond_structure = self.__ontology.get_bond_structure(label_name) # name,level,modality,type,cost,time new_generator = MyGenerator(label_name, level, modalities, 'ontological', cost, time) # set feature location associated to the new candidate new_generator.set_rlocation(g_r.get_rlocation()) # define the bond structure of the generator here new_generator.set_bond_structure(bond_structure) # create a new configuration in which the new candidate replaces the one to be remove #print 'removing generator ',g_r.get_id() new_config = config.replace(g_r, new_generator) # make changes to the connection of the new configuration given the newly added generator for feature_generator in unconnected_feature_generators: self.__place_support_bonds(feature_generator, new_generator, new_config, feature_thresh) self.__place_ontological_bonds(new_generator, new_config) # record newly proposed configs with candidate_configs.append(new_config) candidate_generators.append(new_generator) #self.__update_bonds_after_replacement(new_config,g_f,new_generator) if with_temporal_bonds: #print 'LOCAL PROPOSAL: TRYING TEMPORAL BONDS...' time.sort() # account for temporal bonds linking to the past for i in range(len(candidate_generators)): self.__place_past_ontological_bonds(candidate_generators[i], candidate_configs[i], time[0]) # account for temporal connections linking to the future for i in range(len(candidate_generators)): self.__place_future_ontological_bonds(candidate_generators[i], candidate_configs[i], time[-1]) # compute local energy contributions by new candidates configuration candidate_local_energies = [] for i in range(len(candidate_generators)): # get local energy that is being contributed by new #candidate_configs[i].print_info() local_energy = candidate_configs[i].get_local_energy( candidate_generators[i], self.__bond_weights) #print 'i#', i, ' local energy: ', local_energy candidate_local_energies.append(local_energy) # os.system("read -p 'pause'") # select a candidate according to probability computed based on their locally contributed energy candidate_index = self.__probabilistic_candidate_selection( candidate_local_energies) # update the current configuration to the new one #self.__discard_configuration(config) # check if the upper code is making a copy of this configuration for other purposes new_proposal = candidate_configs[candidate_index] # discard temporary configurations, and others... del candidate_configs[candidate_index] for i in range(len(candidate_configs)): self.__discard_configuration(candidate_configs[0]) del labels return new_proposal
def __construct_new_configuration(self, config, candidates, feature_generator): # follow similar idea of function below... candidate_configs = [] candidate_generators = [] feature_generator.get_time().sort() current_time = feature_generator.get_time()[-1] for i in range(len(candidates)): # collect all data to create a generator label_name = candidates[i] level = self.__ontology.get_level(label_name) modalities = self.__ontology.get_modalities(label_name) bond_structure = self.__ontology.get_bond_structure(label_name) # name,level,modality,type,cost,time ontological_generator = MyGenerator(label_name, level, modalities, 'ontological', 0, [current_time]) # set feature location associated to the new candidate ontological_generator.set_rlocation( feature_generator.get_rlocation()) # define the bond structure of the generator here ontological_generator.set_bond_structure(bond_structure) # create a new configuration in which the new candidate replaces the one to be remove new_config = config.get_copy() new_config.add_generator(ontological_generator) candidate_generators.append(ontological_generator) # make changes to the connection of the new configuration given the newly added generator #self.__update_bonds_after_replacement(new_config, g_f, g_c) self.__place_support_bonds(feature_generator, ontological_generator, new_config) self.__place_ontological_bonds(ontological_generator, new_config) # record newly proposed configs with candidate_configs.append(new_config) # account for temporal bonds linking to the past for i in range(len(candidate_generators)): self.__place_past_ontological_bonds(candidate_generators[i], candidate_configs[i], current_time) # account for temporal connections linking to the future #for i in range(len(candidate_generators)): # self.__place_future_ontological_bonds(candidate_generator[i],candidate_configs[i],current_time) # compute local energy contributions by new candidates configuration candidate_local_energies = [] for i in range(len(candidate_generators)): # get local energy that is being contributed by new local_energy = candidate_configs[i].get_local_energy( candidate_generators[i], self.__bond_weights) candidate_local_energies.append(local_energy) # select a candidate according to probability computed based on their locally contributed energy candidate_index = self.__probabilistic_candidate_selection( candidate_local_energies) # update the current configuration to the new one #self.__discard_configuration(config) # check if the upper code is making a copy of this configuration for other purposes new_config = candidate_configs[candidate_index] # discard temporary configurations, and others... del candidate_configs[candidate_index] for i in range(len(candidate_configs)): self.__discard_configuration(candidate_configs[0]) return new_config
def time_based_propose(self, config, current_time): # probability of maintaining the same explanation change_explanation = True same_state_prob = 0.3 if random.uniform(0, 1) < same_state_prob: change_explanation = False feature_generators = config.get_feature_generators() newly_added_feature_generators = [] past_feature_generators = [] past_feature_generator_connectors = {} past_inbond_labels = [] for feature_generator in feature_generators: if self.__intersect(feature_generator.get_time(), [current_time]): newly_added_feature_generators.append(feature_generator) elif self.__intersect(feature_generator.get_time(), [current_time - self.__time_unit]): past_feature_generators.append(feature_generator) # used to know to which ontological generator to connect # (case when aiming at keeping the same explanation for the new feat generators) past_feature_generator_connectors[ feature_generator.get_id()] = [] for bond in feature_generator.get_outbonds(): # check to which one it is if bond.get_connector() != None: #past_feature_generator_connectors[feature_generator.get_id()].append(bond) if bond.get_value( ) not in past_feature_generator_connectors: past_feature_generator_connectors[ bond.get_value()] = [] past_feature_generator_connectors[ bond.get_value()].append((feature_generator, bond)) for bond in feature_generator.get_inbonds(): #coordinate = bond.get_connector_coordinate() ontological_generator = config.get_generator_by( bond.get_connector()) past_inbond_labels.append(ontological_generator.get_name()) #outbond = ontological_generator.get_outbond_by_coordinate(coordinate) #past_labels.append() #print len(newly_added_feature_generators),' newly added features: ',repr(newly_added_feature_generators) #print len(past_feature_generators),' past feature generators: ',repr(past_feature_generators) #print len(past_inbond_labels),' past inbond labels: ',repr(past_inbond_labels) #any_feature = newly_added_feature_generators[random.randrange(len(newly_added_feature_generators))] if not past_feature_generators and not past_inbond_labels and not len( config.get_ontological_generators()): for feature_generator in newly_added_feature_generators: top_labels = feature_generator.get_top_labels() index = random.randrange(len(top_labels)) label = top_labels[index] #print 'feature: ' + g_f.get_name() #print ' top labels: ' #print 'selected label: ',label.name #print 'level: ',self.__ontology.get_level(label.name) ontological_generator = MyGenerator( label.name, self.__ontology.get_level(label.name), self.__ontology.get_modalities(label.name), 'ontological', label.cost, [current_time]) #print 'feature time: ', feature.time ontological_generator.set_rlocation( feature_generator.get_rlocation()) bond_structure = self.__ontology.get_bond_structure(label.name) ontological_generator.set_bond_structure(bond_structure) config.add_generator(ontological_generator) self.__place_support_bonds(feature_generator, ontological_generator, config) #print 'ontological generators ',len(config.get_ontological_generators()) self.__place_ontological_bonds(ontological_generator, config) return config if not change_explanation: new_ontological_generators = [] for feature_generator in newly_added_feature_generators: #print 'feature id: ',feature_generator.get_id(),' feature name: ',feature_generator.get_name() # for when feature generators's outbonds connect to ontological generators's inbonds for bond in feature_generator.get_outbonds(): #print 'out of outbond connections...' # if current generator can connect to existing concepts already explaining past features if bond.get_value( ) in past_feature_generator_connectors: # escolher a mesma configuracao ou uma nova dada certa probabilidade # find out what the concept is past_bond = past_feature_generator_connectors[ bond.get_value()][1] if bond.get_connector() != past_bond.get_connector(): if bond.get_connector() != None: config.remove_generator(bond.get_connector()) ontological_generator = config.get_generator_by( past_bond.get_connector()) ontological_generator.get_time().append( current_time) self.__place_support_bonds(feature_generator, ontological_generator, config) # for when ontological generators's outbonds connect to feature generators's inbonds context_labels = [] for label in past_inbond_labels: bond_structure = self.__ontology.get_bond_structure(label) for bond in bond_structure: bond_value = bond[0] if self.__intersect([bond_value], feature_generator.get_modality()): context_labels.append(label) if context_labels: #print 'out of inbond connections...' label = context_labels[random.randrange( len(context_labels))] level = self.__ontology.get_level(label) modalities = self.__ontology.get_modalities(label) ontological_generator = MyGenerator( label, level, modalities, 'ontological', 0, [current_time]) ontological_generator.set_rlocation( feature_generator.get_rlocation()) bond_structure = self.__ontology.get_bond_structure(label) ontological_generator.set_bond_structure(bond_structure) # remove old explanation if it exists before proposing a new one #print 'before - number of inbonds: ',len(feature_generator.get_inbonds()) #config.print_info() connectors = [] for inbond in feature_generator.get_inbonds(): connectors.append(inbond.get_connector()) #print 'remove connector ',inbond.get_connector() for generator_id in connectors: config.remove_generator(generator_id) del connectors #print 'after - number of inbonds: ',len(feature_generator.get_inbonds()) config.add_generator(ontological_generator) new_ontological_generators.append(ontological_generator) self.__place_support_bonds(feature_generator, ontological_generator, config) #print 'after connecting new generator: ',len(feature_generator.get_inbonds()) #config.print_info() self.__place_ontological_bonds(ontological_generator, config) # move to explain the next feature generator #past_inbond_labels.remove(label) #break #for generator in new_ontological_generators: return config # print 'NEW EXPLANATIONS BASED ON THE PAST' # if new feature are to receive new explanations based on the past new_ontological_generators = [] for feature_generator in newly_added_feature_generators: # for when feature generators's outbonds connect to ontological generators's inbonds for bond in feature_generator.get_outbonds(): # if current generator can connect to existing concepts already explaining past features if bond.get_value() in past_feature_generator_connectors: # find out what the concept is past_bond = past_feature_generator_connectors[ bond.get_value()][1] generator_id = past_bond.get_connector() g_k = config.get_generator_by(generator_id) # find out the exact interaction # this can be later resolved by having a composite generator that has a name that combines one or more # generators (that will be easier to implement and faster -- only thought of this now) label = g_k.get_name( ) #self.__get_interaction_name(g_k,config) # choose probabilistically whether to propose new explanations for the newly added features # or to make them explain the current configuration state # conditional_cooccurrences = self.__ontology.conditional_cooccurrence('interactions_'+bond.get_value(),label,True,order=1) conditional_cooccurrences = self.__ontology.conditional_cooccurrence( bond.get_value() + '_' + bond.get_value(), label, True, order=1) labels = conditional_cooccurrences.keys() label_counts = conditional_cooccurrences.values() label_index = self.__probabilistic_candidate_selection( label_counts) candidates = [labels[label_index]] else: # get all candidate labels labels = self.__ontology.get_equivalent_labels( bond.get_value()) # select candidates uniformly random candidates = random.sample(labels, max(self.__k, len(labels))) del labels self.__construct_new_configuration(config, candidates, feature_generator) # for when ontological generator's outbonds connect to feature generators's inbonds #connect = False context_labels = [] for label in past_inbond_labels: bond_structure = self.__ontology.get_bond_structure(label) for bond in bond_structure: bond_value = bond[0] if self.__intersect([bond_value], feature_generator.get_modality()): context_labels.append(label) #connect = True if context_labels: label = context_labels[random.randrange(len(context_labels))] level = self.__ontology.get_level(label) #print 'level: ',repr(level) modality = '' if level == 3: modality = 'actions' elif level == 2: modality = 'objects' #print 'modality: ',modality conditional_cooccurrences = self.__ontology.conditional_occurrence( modality + '_' + modality, label, True, order=1) labels = conditional_cooccurrences.keys() #print 'labels: ',repr(labels) label_counts = conditional_cooccurrences.values() index = self.__probabilistic_candidate_selection(label_counts) next_label = labels[index] level = self.__ontology.get_level(next_label) modalities = self.__ontology.get_modalities(next_label) bond_structure = self.__ontology.get_bond_structure(next_label) ontological_generator = MyGenerator(next_label, level, modalities, 'ontological', 0, [current_time]) ontological_generator.set_rlocation( feature_generator.get_rlocation()) ontological_generator.set_bond_structure(bond_structure) config.add_generator(ontological_generator) new_ontological_generators.append(ontological_generator) # remove old explanation if it exists before proposing a new one #print 'before - number of inbonds: ',len(feature_generator.get_inbonds()) #config.print_info() connectors = [] for inbond in feature_generator.get_inbonds(): connectors.append(inbond.get_connector()) #print 'remove connector ',inbond.get_connector() for generator_id in connectors: config.remove_generator(generator_id) del connectors #print 'after - number of inbonds: ',len(feature_generator.get_inbonds()) self.__place_support_bonds(feature_generator, ontological_generator, config) #config.print_info() #print 'after connecting new generator: ',len(feature_generator.get_inbonds()) self.__place_ontological_bonds(ontological_generator, config) # move to explain the next feature generator #past_inbond_labels.remove(label) #break # account for temporal bonds linking to the past for generator in new_ontological_generators: self.__place_past_ontological_bonds(generator, config, current_time) return config