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 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
# 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 new_cycle = NegativeCycle() new_cycle.add_constraint(ep1,0,1) new_cycle.add_constraint(ep1,1,-1) new_cycle.add_constraint(ep2,0,1) new_cycle.add_constraint(ep2,1,-1) new_cycle.add_constraint(ep3,1,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 new_cycle = NegativeCycle() new_cycle.add_constraint(ep1, 0, 1) new_cycle.add_constraint(ep1, 1, -1) new_cycle.add_constraint(ep2, 0, 1) new_cycle.add_constraint(ep2, 1, -1) new_cycle.add_constraint(ep3, 1, 1)