def test_kirk_zipcar11(self): # build a kirk problem # first create a Tpnu tpnu = Tpnu('id','trip') # event # create events for this tpnu node_number_to_id = {} start_event = 1 end_event = 2 node_number_to_id[1] = 'start' node_number_to_id[2] = 'end' event_idx = 3 constraint_idx = 1; # decision variable # create a decision variable to represent the choies over restaurants tpnu_decision_variable = DecisionVariable('dv','where to go?') tpnu.add_decision_variable(tpnu_decision_variable) # Then iterate through all goals and add them as domain assignments goal = 'somewhere' assignment = Assignment(tpnu_decision_variable, 'somewhere', 10.0) tpnu_decision_variable.add_domain_value(assignment) home_to_restaurant = TemporalConstraint('ep-'+str(constraint_idx), 'go to '+str(goal)+'-'+str(constraint_idx), start_event, event_idx, 36.065506858138214, 44.08006393772449) constraint_idx += 1 event_idx += 1 eat_at_restaurant = TemporalConstraint('ep-'+str(constraint_idx), 'dine at '+str(goal)+'-'+str(constraint_idx), event_idx-1, end_event, 0, 30) constraint_idx += 1 node_number_to_id[event_idx-1] = 'arrive-'+str(goal) home_to_restaurant.add_guard(assignment) eat_at_restaurant.add_guard(assignment) tpnu.add_temporal_constraint(home_to_restaurant) tpnu.add_temporal_constraint(eat_at_restaurant) # temporal constraints # create constraints for the duration of the trip tpnu_constraint = TemporalConstraint('tc-'+str(constraint_idx), 'tc-'+str(constraint_idx), start_event, end_event, 0, 15) constraint_idx += 1 tpnu_constraint.relaxable_ub = True tpnu_constraint.relax_cost_ub = 0.1 tpnu.add_temporal_constraint(tpnu_constraint) tpnu.num_nodes = event_idx-1 tpnu.node_number_to_id = node_number_to_id # next formulate a search problem using this tpnu search_problem = SearchProblem(tpnu) search_problem.initialize() solution = search_problem.next_solution()
def __init__(self, tpnu, obj_type): self.network = tpnu self.objective_type = obj_type self.DEFAULT = 100000 self.estimate_default() # no two links share the same end nodes pair_nodes = {} v_new_constraint = {} b_end_unc = {} for e in self.network.temporal_constraints.values(): # print(e.fro, e.to, e.get_lower_bound(), e.get_upper_bound(),e.controllable) if e.controllable: if e.get_upper_bound() > self.DEFAULT: self.network.temporal_constraints[e.id].upper_bound = self.DEFAULT if (e.fro, e.to) in pair_nodes: #print("o", e.fro, e.to) new_node = self.network.num_nodes+1 self.network.num_nodes+=1 new_constraint = TemporalConstraint(new_node, new_node, e.fro, new_node, 0,0) self.network.temporal_constraints[e.id].fro = new_node v_new_constraint[new_constraint.id] = new_constraint #print("s",new_constraint.fro,new_constraint.to, e.fro, e.to) # self.network.add_temporal_constraint(new_constraint) pair_nodes[(e.fro, e.to)] = True else: #print(e.to) b_end_unc[e.to] = True for e in self.network.temporal_constraints.values(): if not e.controllable and e.fro in b_end_unc: new_node = self.network.num_nodes+1 self.network.num_nodes+=1 new_constraint = TemporalConstraint(new_node, new_node, e.fro, new_node, 0,0) self.network.temporal_constraints[e.id].fro = new_node v_new_constraint[new_constraint.id] = new_constraint for e in v_new_constraint.values(): self.network.add_temporal_constraint(e) self.initialize()
def parseCCTP(inFilename): e = xml.etree.ElementTree.parse(inFilename).getroot() tpnu_name = e.find('NAME').text tpnu = Tpnu('', tpnu_name) # In TPN format every node (or event in TPN terminology) has a non-unique name # and an unique id. Both of those are strings. For efficiency DC checking algorithms # denote each node by a number, such that we can cheaply check their equality. # parse the event event_ids = set() tpnu.node_id_to_name = {} # tpnu.node_name_to_number = {} tpnu.node_number_to_id = {} tpnu.node_id_to_number = {} for event_obj in e.findall('EVENT'): eid, ename = event_obj.find('ID').text, event_obj.find('NAME').text event_ids.add(eid) tpnu.node_id_to_name[eid] = ename for eid in event_ids: next_number = len(tpnu.node_number_to_id) + 1 tpnu.node_number_to_id[next_number] = eid tpnu.node_id_to_number[eid] = next_number # tpnu.node_name_to_number[tpnu.node_id_to_name[eid]] = next_number tpnu.num_nodes = len(tpnu.node_number_to_id) start_id = e.find('START').text tpnu.start_node = tpnu.node_id_to_number[start_id] if (tpnu.num_nodes < 1): return None # parse the decision variables assignment_map_with_id = {} assignment_map_with_name = {} for variable_obj in e.findall('DECISION-VARIABLE'): dv_name = variable_obj.find('DECISION-NAME').text if variable_obj.find('ID') is not None: dv_id = variable_obj.find('ID').text else: dv_id = dv_name decision_variable = DecisionVariable(dv_id, dv_name) # construct the assignment for the variable for value_obj in variable_obj.findall('VALUE'): # value_id = value_obj.find('ID').text value_name = value_obj.find('VALUE-NAME').text value_utility = float(value_obj.find('VALUE-UTILITY').text) assignment = Assignment(decision_variable, value_name, value_utility) # add the assignment to the variable, and a dictionary for future reference decision_variable.add_domain_value(assignment) # using the id of the variable and the value of the assignment as key assignment_map_with_id[(dv_id, value_name)] = assignment assignment_map_with_name[(dv_name, value_name)] = assignment tpnu.add_decision_variable(decision_variable) # parse variables' guards for variable_obj in e.findall('DECISION-VARIABLE'): if variable_obj.find('ID') is not None: dv_id = variable_obj.find('ID').text else: dv_id = variable_obj.find('DECISION-NAME').text decision_variable = tpnu.decision_variables[dv_id] # the guard could be a conjunctive set of assignment for guard_obj in variable_obj.findall('GUARD'): # guard_id = guard_obj.find('ID').text guard_variable = guard_obj.find('GUARD-VARIABLE').text guard_value = guard_obj.find('GUARD-VALUE').text # retrieve the assignment if (guard_variable, guard_value) in assignment_map_with_id: guard_assignment = assignment_map_with_id[(guard_variable, guard_value)] elif (guard_variable, guard_value) in assignment_map_with_name: guard_assignment = assignment_map_with_name[( guard_variable, guard_value)] # and add to the guards of this decision variable decision_variable.add_guard(guard_assignment) # parse the temporal constraints and episodes # if line below confuses you, that's expected... We need better automated code generation for parsing... for constraint_obj in e.findall('CONSTRAINT'): # duration can be one of three types - controllable, uncertain and probabilistic # here we are only handling the first two cases, which are sorted into two lists # in our resulting stnu class. lower_bound = float(constraint_obj.find('LOWERBOUND').text) upper_bound = float(constraint_obj.find('UPPERBOUND').text) from_event = constraint_obj.find('START').text to_event = constraint_obj.find('END').text constraint_id = constraint_obj.find('ID').text constraint_name = constraint_obj.find('NAME').text constraint = TemporalConstraint(constraint_id, constraint_name, tpnu.node_id_to_number[from_event], tpnu.node_id_to_number[to_event], lower_bound, upper_bound) # check if the constraint is controllable and relaxable type = constraint_obj.find('TYPE').text if "Controllable" in type: constraint.controllable = True elif "Uncontrollable" in type: constraint.controllable = False if constraint_obj.find('MEAN') is not None: constraint.mean = float(constraint_obj.find('MEAN').text) if constraint_obj.find('VARIANCE') is not None: constraint.probabilistic = True constraint.std = np.sqrt( float(constraint_obj.find('VARIANCE').text)) if constraint_obj.find('LBRELAXABLE') is not None: if "T" in constraint_obj.find('LBRELAXABLE').text: constraint.relaxable_lb = True lb_cost = constraint_obj.find('LB-RELAX-COST-RATIO').text constraint.relax_cost_lb = float(lb_cost) if constraint_obj.find('UBRELAXABLE') is not None: if "T" in constraint_obj.find('UBRELAXABLE').text: constraint.relaxable_ub = True ub_cost = constraint_obj.find('UB-RELAX-COST-RATIO').text constraint.relax_cost_ub = float(ub_cost) # Next we deal with the guard conditions # the approach is identical to that for decision variables for guard_obj in constraint_obj.findall('GUARD'): # guard_id = guard_obj.find('ID').text guard_variable = guard_obj.find('GUARD-VARIABLE').text guard_value = guard_obj.find('GUARD-VALUE').text # retrieve the assignment if (guard_variable, guard_value) in assignment_map_with_id: guard_assignment = assignment_map_with_id[(guard_variable, guard_value)] elif (guard_variable, guard_value) in assignment_map_with_name: guard_assignment = assignment_map_with_name[( guard_variable, guard_value)] # and add to the guards of this decision variable constraint.add_guard(guard_assignment) tpnu.add_temporal_constraint(constraint) # Parse Chance Constraint # risk_bound = float(e.find('RISK-BOUND').text) # risk_bound_relax_cost = float(e.find('RISK-BOUND-RELAX-COST').text) risk_bound = 0.05 risk_bound_relax_cost = 100 cc_constraint = ChanceConstraint("CC-1", "CC-Constraint", risk_bound) if risk_bound_relax_cost > 0: cc_constraint.relaxable_bound = True cc_constraint.relax_cost = risk_bound_relax_cost tpnu.add_chance_constraint(cc_constraint) tpnu.start_node = tpnu.node_id_to_number[start_id] return tpnu
def from_tpn_autogen(tpn): tpn_id = tpn.get_id() tpn_name = tpn.get_name() tpnu = Tpnu(tpn_id, tpn_name) # In TPN format every node (or event in TPN terminology) has a non-unique name # and an unique id. Both of those are strings. For efficiency DC checking algorithms # denote each node by a number, such that we can cheaply check their equality. # parse the event event_ids = set() tpnu.node_id_to_name = {} tpnu.node_number_to_id = {} tpnu.node_id_to_number = {} for event in tpn.get_events().get_event(): eid, ename = event.get_id(), event.get_name() event_ids.add(eid) tpnu.node_id_to_name[eid] = ename for eid in event_ids: next_number = len(tpnu.node_number_to_id) + 1 tpnu.node_number_to_id[next_number] = eid tpnu.node_id_to_number[eid] = next_number tpnu.num_nodes = len(tpnu.node_number_to_id) assignment_map = {} # parse the decision variables for tpn_dv in tpn.get_decision_variables().get_decision_variable(): dv_id = tpn_dv.get_id() dv_name = tpn_dv.get_name() decision_variable = DecisionVariable(dv_id, dv_name) # construct the assignment for the variable for domain_value in tpn_dv.get_domain().get_domainval(): value_name = domain_value.get_value() value_utility = domain_value.get_utility() assignment = Assignment(decision_variable, value_name, value_utility) # add the assignment to the variable, and a dictionary for future reference decision_variable.add_domain_value(assignment) # using the id of the variable and the value of the assignment as key assignment_map[(dv_id, value_name)] = assignment tpnu.add_decision_variable(decision_variable) # parse their guards for tpn_dv in tpn.get_decision_variables().get_decision_variable(): dv_id = tpn_dv.get_id() decision_variable = tpnu.decision_variables[dv_id] # the guard could be a single value # or a conjunctive set of assignment single_guard = tpn_dv.get_guard().get_decision_variable_equals() guard_list = tpn_dv.get_guard().get_and() if single_guard is not None: guard_variable_id = single_guard.get_variable() guard_value = single_guard.get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id, guard_value)] # and add to the guards of this decision variable decision_variable.add_guard(guard_assignment) if guard_list is not None: for guard in guard_list.get_guard(): guard_variable_id = guard.get_decision_variable_equals( ).get_variable() guard_value = guard.get_decision_variable_equals( ).get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id, guard_value)] # and add to the guards of this decision variable decision_variable.add_guard(guard_assignment) # parse the temporal constraints and episodes # if line below confuses you, that's expected... We need better automated code generation for parsing... for temporal_constraint in tpn.get_temporal_constraints( ).get_temporal_constraint() + tpn.get_episodes().get_episode(): # duration can be one of three types - controllable, uncertain and probabilistic # here we are only handling the first two cases, which are sorted into two lists # in our resulting stnu class. controllable_duration = temporal_constraint.get_duration( ).get_bounded_duration() uncertain_duration = temporal_constraint.get_duration( ).get_set_bounded_uncertain_duration() duration = controllable_duration or uncertain_duration lower_bound = duration.get_lower_bound() upper_bound = duration.get_upper_bound() from_event = temporal_constraint.get_from_event() to_event = temporal_constraint.get_to_event() constraint_id = temporal_constraint.get_id() constraint_name = temporal_constraint.get_name() constraint = TemporalConstraint(constraint_id, constraint_name, tpnu.node_id_to_number[from_event], tpnu.node_id_to_number[to_event], lower_bound, upper_bound) if controllable_duration is not None: constraint.controllable = True constraint.relaxable_ub = True elif uncertain_duration is not None: constraint.controllable = False # Next we deal with the guard conditions # the approach is identical to that for decision variables # the guard could be a single value # or a conjunctive set of assignment single_guard = temporal_constraint.get_guard( ).get_decision_variable_equals() guard_list = temporal_constraint.get_guard().get_and() if single_guard is not None: guard_variable_id = single_guard.get_variable() guard_value = single_guard.get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id, guard_value)] # and add to the guards of this decision variable constraint.add_guard(guard_assignment) if guard_list is not None: for guard in guard_list.get_guard(): guard_variable_id = guard.get_decision_variable_equals( ).get_variable() guard_value = guard.get_decision_variable_equals( ).get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id, guard_value)] # and add to the guards of this decision variable constraint.add_guard(guard_assignment) tpnu.add_temporal_constraint(constraint) return tpnu
# NOTE: Limitation: Assumes num_nodes = N, then events are indexed by 1, 2, ..., N # TODO: Currently, Tpnu.from_tpn_autogen does map eventID to numbers, but it does not take TPNU as input, if we want to use arbitrary event names, we need to add such a function/mapping tpnu = Tpnu(str(uuid4()), 'example-tpnu') tpnu.start_node = 1 tpnu.num_nodes = 3 # Initialize a decision variable dv = DecisionVariable(str(uuid4()), 'dv') as1 = Assignment(dv, 'dv-true', 10) as2 = Assignment(dv, 'dv-false', 3) dv.add_domain_value(as1) dv.add_domain_value(as2) tpnu.add_decision_variable(dv) # Initialize temporal constraints tc1 = TemporalConstraint(str(uuid4()), 'tc1', 1, 2, 0, 10) tc1.controllable = False tpnu.add_temporal_constraint(tc1) tc2 = TemporalConstraint(str(uuid4()), 'tc2', 2, 3, 0, 10) tc2.controllable = False tpnu.add_temporal_constraint(tc2) tc3 = TemporalConstraint(str(uuid4()), 'tc3', 1, 3, 0, 15) tc3.add_guard(as1) tc3.relaxable_ub = True tc3.relaxable_lb = False tc3.relax_cost_ub = 1 tpnu.add_temporal_constraint(tc3) # tpnu = Tpnu.from_tpn_autogen() print(tpnu)
G[2 * idx] = truncnorm.pdf(x[lb_var], a,b, loc=mean, scale=sigma) # For the upper bound, it is the negation of the Gaussian pdf G[2 * idx + 1] = -1 * truncnorm.pdf(x[ub_var], a,b, loc=mean, scale=sigma) # print('Updating G['+str(2 * idx)+']: ' + str(G[2 * idx])) # print('Updating G['+str(2 * idx+1)+']: ' + str(G[2 * idx + 1])) if __name__ == "__main__": candidate = Candidate() ev1 = 1 ev2 = 2 ev3 = 3 ep1 = TemporalConstraint('ep-1','ep-1', ev1, ev2, 15,30) ep2 = TemporalConstraint('ep-2','ep-2', ev2, ev3, 15,30) ep3 = TemporalConstraint('ep-3','ep-3', ev1, ev3, 40,40) ep1.controllable = False ep1.probabilistic = True ep1.mean = 150 ep1.std = 5 ep2.controllable = False ep2.probabilistic = True ep2.mean = 150 ep2.std = 5 ep3.relaxable_ub = True ep3.relax_cost_ub = 0.1
def parseCCTP(inFilename): e = xml.etree.ElementTree.parse(inFilename).getroot() tpnu_name = e.find('NAME').text tpnu = Tpnu('', tpnu_name) # In TPN format every node (or event in TPN terminology) has a non-unique name # and an unique id. Both of those are strings. For efficiency DC checking algorithms # denote each node by a number, such that we can cheaply check their equality. # parse the event event_ids = set() tpnu.node_id_to_name = {} tpnu.node_number_to_id = {} tpnu.node_id_to_number = {} for event_obj in e.findall('EVENT'): eid, ename = event_obj.find('ID').text, event_obj.find('NAME').text event_ids.add(eid) tpnu.node_id_to_name[eid] = ename for eid in event_ids: next_number = len(tpnu.node_number_to_id) + 1 tpnu.node_number_to_id[next_number] = eid tpnu.node_id_to_number[eid] = next_number tpnu.num_nodes = len(tpnu.node_number_to_id) start_id = e.find('START').text tpnu.start_node = tpnu.node_id_to_number[start_id] if (tpnu.num_nodes < 1): return None # parse the decision variables assignment_map_with_id = {} assignment_map_with_name = {} for variable_obj in e.findall('DECISION-VARIABLE'): dv_name = variable_obj.find('DECISION-NAME').text if variable_obj.find('ID') is not None: dv_id = variable_obj.find('ID').text else: dv_id = dv_name decision_variable = DecisionVariable(dv_id,dv_name) # construct the assignment for the variable for value_obj in variable_obj.findall('VALUE'): # value_id = value_obj.find('ID').text value_name = value_obj.find('VALUE-NAME').text value_utility = float(value_obj.find('VALUE-UTILITY').text) assignment = Assignment(decision_variable, value_name, value_utility) # add the assignment to the variable, and a dictionary for future reference decision_variable.add_domain_value(assignment) # using the id of the variable and the value of the assignment as key assignment_map_with_id[(dv_id,value_name)] = assignment assignment_map_with_name[(dv_name,value_name)] = assignment tpnu.add_decision_variable(decision_variable) # parse variables' guards for variable_obj in e.findall('DECISION-VARIABLE'): if variable_obj.find('ID') is not None: dv_id = variable_obj.find('ID').text else: dv_id = variable_obj.find('DECISION-NAME').text decision_variable = tpnu.decision_variables[dv_id] # the guard could be a conjunctive set of assignment for guard_obj in variable_obj.findall('GUARD'): # guard_id = guard_obj.find('ID').text guard_variable = guard_obj.find('GUARD-VARIABLE').text guard_value = guard_obj.find('GUARD-VALUE').text # retrieve the assignment if (guard_variable,guard_value) in assignment_map_with_id: guard_assignment = assignment_map_with_id[(guard_variable,guard_value)] elif (guard_variable,guard_value) in assignment_map_with_name: guard_assignment = assignment_map_with_name[(guard_variable,guard_value)] # and add to the guards of this decision variable decision_variable.add_guard(guard_assignment) # parse the temporal constraints and episodes # if line below confuses you, that's expected... We need better automated code generation for parsing... for constraint_obj in e.findall('CONSTRAINT'): # duration can be one of three types - controllable, uncertain and probabilistic # here we are only handling the first two cases, which are sorted into two lists # in our resulting stnu class. lower_bound = float(constraint_obj.find('LOWERBOUND').text) upper_bound = float(constraint_obj.find('UPPERBOUND').text) from_event = constraint_obj.find('START').text to_event = constraint_obj.find('END').text constraint_id = constraint_obj.find('ID').text constraint_name = constraint_obj.find('NAME').text constraint = TemporalConstraint(constraint_id, constraint_name, tpnu.node_id_to_number[from_event], tpnu.node_id_to_number[to_event], lower_bound, upper_bound) # check if the constraint is controllable and relaxable type = constraint_obj.find('TYPE').text if "Controllable" in type: constraint.controllable = True elif "Uncontrollable" in type: constraint.controllable = False if constraint_obj.find('MEAN') is not None: constraint.mean = float(constraint_obj.find('MEAN').text) if constraint_obj.find('VARIANCE') is not None: constraint.probabilistic = True constraint.std = np.sqrt(float(constraint_obj.find('VARIANCE').text)) if constraint_obj.find('LBRELAXABLE') is not None: if "T" in constraint_obj.find('LBRELAXABLE').text: constraint.relaxable_lb = True lb_cost = constraint_obj.find('LB-RELAX-COST-RATIO').text constraint.relax_cost_lb = float(lb_cost) if constraint_obj.find('UBRELAXABLE') is not None: if "T" in constraint_obj.find('UBRELAXABLE').text: constraint.relaxable_ub = True ub_cost = constraint_obj.find('UB-RELAX-COST-RATIO').text constraint.relax_cost_ub = float(ub_cost) # Next we deal with the guard conditions # the approach is identical to that for decision variables for guard_obj in constraint_obj.findall('GUARD'): # guard_id = guard_obj.find('ID').text guard_variable = guard_obj.find('GUARD-VARIABLE').text guard_value = guard_obj.find('GUARD-VALUE').text # retrieve the assignment if (guard_variable,guard_value) in assignment_map_with_id: guard_assignment = assignment_map_with_id[(guard_variable,guard_value)] elif (guard_variable,guard_value) in assignment_map_with_name: guard_assignment = assignment_map_with_name[(guard_variable,guard_value)] # and add to the guards of this decision variable constraint.add_guard(guard_assignment) tpnu.add_temporal_constraint(constraint) # Parse Chance Constraint # risk_bound = float(e.find('RISK-BOUND').text) # risk_bound_relax_cost = float(e.find('RISK-BOUND-RELAX-COST').text) risk_bound = 0.05 risk_bound_relax_cost = 100 cc_constraint = ChanceConstraint("CC-1", "CC-Constraint", risk_bound) if risk_bound_relax_cost > 0: cc_constraint.relaxable_bound = True cc_constraint.relax_cost = risk_bound_relax_cost tpnu.add_chance_constraint(cc_constraint) tpnu.start_node = tpnu.node_id_to_number[start_id] return tpnu
def from_tpn_autogen(tpn): tpn_id = tpn.get_id() tpn_name = tpn.get_name() tpnu = Tpnu(tpn_id, tpn_name) # In TPN format every node (or event in TPN terminology) has a non-unique name # and an unique id. Both of those are strings. For efficiency DC checking algorithms # denote each node by a number, such that we can cheaply check their equality. # parse the event event_ids = set() tpnu.node_id_to_name = {} tpnu.node_number_to_id = {} tpnu.node_id_to_number = {} for event in tpn.get_events().get_event(): eid, ename = event.get_id(), event.get_name() event_ids.add(eid) tpnu.node_id_to_name[eid] = ename for eid in event_ids: next_number = len(tpnu.node_number_to_id) + 1 tpnu.node_number_to_id[next_number] = eid tpnu.node_id_to_number[eid] = next_number tpnu.num_nodes = len(tpnu.node_number_to_id) assignment_map = {} # parse the decision variables for tpn_dv in tpn.get_decision_variables().get_decision_variable(): dv_id = tpn_dv.get_id() dv_name = tpn_dv.get_name() decision_variable = DecisionVariable(dv_id,dv_name) # construct the assignment for the variable for domain_value in tpn_dv.get_domain().get_domainval(): value_name = domain_value.get_value() value_utility = domain_value.get_utility() assignment = Assignment(decision_variable, value_name, value_utility) # add the assignment to the variable, and a dictionary for future reference decision_variable.add_domain_value(assignment) # using the id of the variable and the value of the assignment as key assignment_map[(dv_id,value_name)] = assignment tpnu.add_decision_variable(decision_variable) # parse their guards for tpn_dv in tpn.get_decision_variables().get_decision_variable(): dv_id = tpn_dv.get_id() decision_variable = tpnu.decision_variables[dv_id] # the guard could be a single value # or a conjunctive set of assignment single_guard = tpn_dv.get_guard().get_decision_variable_equals() guard_list = tpn_dv.get_guard().get_and() if single_guard is not None: guard_variable_id = single_guard.get_variable() guard_value = single_guard.get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id,guard_value)] # and add to the guards of this decision variable decision_variable.add_guard(guard_assignment) if guard_list is not None: for guard in guard_list.get_guard(): guard_variable_id = guard.get_decision_variable_equals().get_variable() guard_value = guard.get_decision_variable_equals().get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id,guard_value)] # and add to the guards of this decision variable decision_variable.add_guard(guard_assignment) # parse the temporal constraints and episodes # if line below confuses you, that's expected... We need better automated code generation for parsing... for temporal_constraint in tpn.get_temporal_constraints().get_temporal_constraint() + tpn.get_episodes().get_episode(): # duration can be one of three types - controllable, uncertain and probabilistic # here we are only handling the first two cases, which are sorted into two lists # in our resulting stnu class. controllable_duration = temporal_constraint.get_duration().get_bounded_duration() uncertain_duration = temporal_constraint.get_duration().get_set_bounded_uncertain_duration() duration = controllable_duration or uncertain_duration lower_bound = duration.get_lower_bound() upper_bound = duration.get_upper_bound() from_event = temporal_constraint.get_from_event() to_event = temporal_constraint.get_to_event() constraint_id = temporal_constraint.get_id() constraint_name = temporal_constraint.get_name() constraint = TemporalConstraint(constraint_id, constraint_name, tpnu.node_id_to_number[from_event], tpnu.node_id_to_number[to_event], lower_bound, upper_bound) if controllable_duration is not None: constraint.controllable = True constraint.relaxable_ub = True elif uncertain_duration is not None: constraint.controllable = False # Next we deal with the guard conditions # the approach is identical to that for decision variables # the guard could be a single value # or a conjunctive set of assignment single_guard = temporal_constraint.get_guard().get_decision_variable_equals() guard_list = temporal_constraint.get_guard().get_and() if single_guard is not None: guard_variable_id = single_guard.get_variable() guard_value = single_guard.get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id,guard_value)] # and add to the guards of this decision variable constraint.add_guard(guard_assignment) if guard_list is not None: for guard in guard_list.get_guard(): guard_variable_id = guard.get_decision_variable_equals().get_variable() guard_value = guard.get_decision_variable_equals().get_value() # retrieve the assignment guard_assignment = assignment_map[(guard_variable_id,guard_value)] # and add to the guards of this decision variable constraint.add_guard(guard_assignment) tpnu.add_temporal_constraint(constraint) return tpnu
# For the upper bound, it is the negation of the Gaussian pdf G[2 * idx + 1] = -1 * truncnorm.pdf(x[ub_var], a, b, loc=mean, scale=sigma) # print('Updating G['+str(2 * idx)+']: ' + str(G[2 * idx])) # print('Updating G['+str(2 * idx+1)+']: ' + str(G[2 * idx + 1])) if __name__ == "__main__": candidate = Candidate() ev1 = 1 ev2 = 2 ev3 = 3 ep1 = TemporalConstraint('ep-1', 'ep-1', ev1, ev2, 15, 30) ep2 = TemporalConstraint('ep-2', 'ep-2', ev2, ev3, 15, 30) ep3 = TemporalConstraint('ep-3', 'ep-3', ev1, ev3, 40, 40) ep1.controllable = False ep1.probabilistic = True ep1.mean = 150 ep1.std = 5 ep2.controllable = False ep2.probabilistic = True ep2.mean = 150 ep2.std = 5 ep3.relaxable_ub = True ep3.relax_cost_ub = 0.1