def set_transition_constrs(self): self.constrs['transition'] = [] for k in range(self.num_futures): for h in range(1, self.problem.horizon): for v in self.problem.variables: # Clique: MSB[n1(h-1), n2(h-1),..., v(h-1), v(h), set(v, h-1)]LSB neighbours = self.neighbours[v] var_indices = [ self.var_to_idx[(self.find_matching_action(v), k, h - 1)], self.var_to_idx[(v, k, h)], self.var_to_idx[(v, k, h - 1)] ] var_indices.extend( [self.var_to_idx[(n, k, h - 1)] for n in neighbours]) num_vars = len(var_indices) determinized_transition = {} clique = MRFClique(var_indices) clique.function_table = [] for clique_bitmask in range(2**num_vars): dependencies_bitmask = ( (clique_bitmask >> 2) << 1) | (clique_bitmask & 1) if dependencies_bitmask in determinized_transition: determinized_val = determinized_transition[ dependencies_bitmask] else: is_set = (clique_bitmask & 1) != 0 num_set_neighbours = self.count_set_neighbours( clique_bitmask, len(neighbours)) is_alive = (clique_bitmask & 2) != 0 if (is_alive and num_set_neighbours in (2, 3)) \ or (not is_alive and num_set_neighbours == 3) \ or is_set: if random.random() <= (1. - self.noise_probs[v]): determinized_val = 1 else: determinized_val = 0 else: if random.random() <= self.noise_probs[v]: determinized_val = 1 else: determinized_val = 0 determinized_transition[ dependencies_bitmask] = determinized_val if (clique_bitmask & 2) >> 1 == determinized_val: clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) self.constrs['transition'].append(clique) logger.info('set_transition_constraints')
def add_reward_constrs(self): for k in range(self.num_futures): for h in range(self.problem.horizon): clique = MRFClique([self.var_to_idx[(self.goal, k, h)]]) clique.function_table = [math.exp(x) for x in [-1, 0]] self.constrs['reward'].append(clique) logger.info('Added reward constraints')
def add_reward_constrs(self): for k in range(self.num_futures): for h in range(self.problem.horizon): for y in self.inst_params['ys']: clique = MRFClique([self.var_to_idx[y, k, h]]) clique.function_table = [math.exp(i) for i in [0, 1]] self.constrs['reward'].append(clique) logger.info('Added reward constraints')
def add_reward_constrs(self): right_dir_penalty = self.inst_params['ELEVATOR-PENALTY-RIGHT-DIR'] wrong_dir_penalty = self.inst_params['ELEVATOR-PENALTY-WRONG-DIR'] for k in range(self.num_futures): for h in range(self.problem.horizon): for elevator in self.inst_params['elevators']: elevator_dir_up = self.get_elevator_dir_state(elevator, 'up') person_going_up = self.get_person_in_elevator_state(elevator, 'up') person_going_down = self.get_person_in_elevator_state(elevator, 'down') clique = MRFClique([self.var_to_idx[elevator_dir_up, k, h], self.var_to_idx[person_going_up, k, h]]) clique.function_table = [1, 1, math.exp(-wrong_dir_penalty), math.exp(-right_dir_penalty)] self.constrs['reward'].append(clique) clique = MRFClique([self.var_to_idx[elevator_dir_up, k, h], self.var_to_idx[person_going_down, k, h]]) clique.function_table = [1, 1, math.exp(-right_dir_penalty), math.exp(-wrong_dir_penalty)] self.constrs['reward'].append(clique) for fl in self.inst_params['floors']: person_waiting_up = self.get_person_waiting_state(fl, 'up') person_waiting_down = self.get_person_waiting_state(fl, 'down') clique = MRFClique([self.var_to_idx[person_waiting_up, k, h], self.var_to_idx[person_waiting_down, k, h]]) clique.function_table = [math.exp(val) for val in [0, -1, -1, -2]] self.constrs['reward'].append(clique) logger.info('Added reward constraints')
def add_reward_constrs(self): function_table = [math.exp(x) for x in [0, 1, -1, 0]] for k in range(self.num_futures): for h in range(self.problem.horizon): for v in self.problem.variables: a = self.find_matching_action(v) vars_indices = [ self.var_to_idx[(v, k, h)], self.var_to_idx[(a, k, h)] ] clique = MRFClique(vars_indices) clique.function_table = function_table self.constrs['reward'].append(clique) logger.info('Added reward constraints')
def add_states_clique(self, determinized_tree, tree_vars, k, t, v): """ Adds a clique i.e. a potential function that represents a determinized transition tree. The function maps to 1 or 0 whether the values assigned to the variables in the tree satisfies the determinized value or not respectively :param determinized_tree: a determinized transition tree :param tree_vars: all variables in the transition tree :param k: the future value :param t: the horizon step :param v: name of state variable to make the transition to """ var_indices = [self.get_state_var_index(v, k, t + 1)] var_indices.extend(self.state_vars_to_indices(tree_vars, k, t)) clique = MRFClique(var_indices) clique.generate_states_function_table(determinized_tree, tree_vars) self.cliques['states'].append(clique)
def set_person_waiting_transition(self, k, h): for floor in self.inst_params['floors']: person_waiting_up = self.get_person_waiting_state(floor, 'up') elevator_states = [(self.get_elevator_at_state(e, floor), self.get_elevator_dir_state(e, 'up'), self.get_elevator_closed_state(e)) for e in self.inst_params['elevators']] var_indices = [self.var_to_idx[person_waiting_up, k, h], self.var_to_idx[person_waiting_up, k, h-1]] var_indices += [self.var_to_idx[es, k, h-1] for es in itertools.chain(*elevator_states)] clique = MRFClique(var_indices) for bitmask in range(2**len(var_indices)): is_elevator_available = False for i in range(len(elevator_states)): if (utils.is_set(bitmask, 2+i*3) and utils.is_set(bitmask, 3+i*3) and not utils.is_set(bitmask, 4+i*3)): is_elevator_available = True if utils.is_set(bitmask, 1) and not is_elevator_available: if utils.is_set(bitmask, 0): clique.function_table.append(1) else: clique.function_table.append(mrf.INVALID_POTENTIAL_VAL) else: determinized_val = 0 if random.random() < self.get_arrive_prob(floor): determinized_val = 1 if utils.match_determinized_val(bitmask, 0, determinized_val): clique.function_table.append(1) else: clique.function_table.append(mrf.INVALID_POTENTIAL_VAL) self.constrs['transition'].append(clique)
def set_init_states_constrs(self, init_state_vals): self.constrs['init_states'] = [] function_table_0 = [1, mrf.INVALID_POTENTIAL_VAL_2] function_table_1 = [mrf.INVALID_POTENTIAL_VAL_2, 1] for k in range(self.num_futures): for v in self.problem.variables: vars_indices = [self.var_to_idx[(v, k, 0)]] clique = MRFClique(vars_indices) if init_state_vals[v] == 0: clique.function_table = function_table_0 else: clique.function_table = function_table_1 self.constrs['init_states'].append(clique) logger.info('set_init_states_constraints')
def add_init_actions_cliques(self): function_table = [] allset = 2**self.num_futures - 1 for i in range(2**self.num_futures): if i == 0 or i == allset: function_table.append(1) else: function_table.append(INVALID_POTENTIAL_VAL) for action in self.problem.actions: vars_indices = [self.get_state_var_index(action, k, 0) for k in range(self.num_futures)] clique = MRFClique(vars_indices) clique.function_table = function_table self.cliques['init_actions'].append(clique) logger.info('added_init_actions_cliques|#init_actions_cliques={}' .format(len(self.cliques['init_actions'])))
def set_transition_constrs(self): self.constrs['transition'] = [] for k in range(self.num_futures): for h in range(1, self.problem.horizon): xindices = [ self.var_to_idx[x, k, h - 1] for x in self.inst_params['xs'] ] aindices = [ self.var_to_idx[a, k, h - 1] for a in self.problem.actions ] num_xs = len(xindices) for x in self.inst_params['xs']: clique = MRFClique([self.var_to_idx[x, k, h]]) determinized_val = 1 if random.random() < 0.5 else 0 utils.append_function_entry(clique, 0, 0, determinized_val) utils.append_function_entry(clique, 1, 0, determinized_val) self.constrs['transition'].append(clique) for y in self.inst_params['ys']: var_indices = [ self.var_to_idx[y, k, h], self.var_to_idx[y, k, h - 1] ] var_indices.extend(xindices) var_indices.extend(aindices) clique = MRFClique(var_indices) for bitmask in range(2**len(var_indices)): if utils.is_set(bitmask, 1): utils.append_function_entry(clique, bitmask, 0, 1) continue matched = True for i in range(2, 2 + num_xs): if utils.is_set(bitmask, i) != utils.is_set( bitmask, i + num_xs): matched = False break if matched and random.random() < 0.49: utils.append_function_entry(clique, bitmask, 0, 1) else: utils.append_function_entry(clique, bitmask, 0, 0) self.constrs['transition'].append(clique) logger.info('set_transition_constraints')
def add_concurrency_constrs(self): function_table = [] for i in range(2**len(self.problem.actions)): if utils.count_set_bits(i) > self.problem.max_concurrency: function_table.append(INVALID_POTENTIAL_VAL) else: function_table.append(1) for k in range(self.num_futures): for t in range(self.problem.horizon): vars_indices = self.state_vars_to_indices(self.problem.actions, k, t) clique = MRFClique(vars_indices) clique.function_table = function_table self.cliques['concurrency'].append(clique) logger.info('added_concurrency_constrs|#concurrency_constrs_cliques={}' .format(len(self.cliques['concurrency'])))
def add_concurrency_constrs(self): function_table = [] for i in range(2**len(self.problem.actions)): if utils.count_set_bits(i) > self.problem.max_concurrency: function_table.append(mrf.INVALID_POTENTIAL_VAL_2) else: function_table.append(1) for k in range(self.num_futures): for h in range(self.problem.horizon): vars_indices = [ self.var_to_idx[(action, k, h)] for action in self.problem.actions ] clique = MRFClique(vars_indices) clique.function_table = function_table self.constrs['concurrency'].append(clique) logger.info('Added concurrency constraints')
def add_init_actions_constrs(self): function_table = [] allset = 2**self.num_futures - 1 for i in range(2**self.num_futures): if i == 0 or i == allset: function_table.append(1) else: function_table.append(mrf.INVALID_POTENTIAL_VAL) for action in self.problem.actions: vars_indices = [ self.var_to_idx[(action, k, 0)] for k in range(self.num_futures) ] clique = MRFClique(vars_indices) clique.function_table = function_table self.constrs['init_actions'].append(clique) logger.info('Added init actions constraints')
def set_elevator_at_floor_transition(self, k, h): for elevator in self.inst_params['elevators']: for floor in self.inst_params['floors']: adjacent_floors = [] upper_floor_idx = len(adjacent_floors) if floor in self.inst_params['ADJACENT-UP'] else None if upper_floor_idx is not None: adjacent_floors.append(self.inst_params['ADJACENT-UP'][floor]) lower_floor_idx = len(adjacent_floors) if floor in self.inst_params['ADJACENT-DOWN'] else None if lower_floor_idx is not None: adjacent_floors.append(self.inst_params['ADJACENT-DOWN'][floor]) elevator_at_floor = self.get_elevator_at_state(elevator, floor) elevator_closed = self.get_elevator_closed_state(elevator) elevator_dir_up = self.get_elevator_dir_state(elevator, 'up') move_cur_dir = self.get_move_current_dir_action(elevator) at_adjacent_floors = [self.get_elevator_at_state(elevator, fl) for fl in adjacent_floors] var_indices = [elevator_at_floor, elevator_at_floor, elevator_closed, elevator_dir_up, move_cur_dir] var_indices += at_adjacent_floors var_indices[0] = self.var_to_idx[var_indices[0], k, h] var_indices[1:] = [self.var_to_idx[v, k, h - 1] for v in var_indices[1:]] adjacent_floors_offset = 5 clique = MRFClique(var_indices) for bitmask in range(2**len(var_indices)): prev_val = utils.btoi(utils.is_set(bitmask, 1)) if not utils.is_set(bitmask, 2) or not utils.is_set(bitmask, 4): utils.append_function_entry(clique, bitmask, 0, prev_val) continue if utils.is_set(bitmask, 4) and utils.is_set(bitmask, 3): if lower_floor_idx is not None: if utils.is_set(bitmask, adjacent_floors_offset + lower_floor_idx): utils.append_function_entry(clique, bitmask, 0, 1) else: utils.append_function_entry(clique, bitmask, 0, 0) else: utils.append_function_entry(clique, bitmask, 0, prev_val) continue if utils.is_set(bitmask, 4) and not utils.is_set(bitmask, 3): if upper_floor_idx is not None: if utils.is_set(bitmask, adjacent_floors_offset + upper_floor_idx): utils.append_function_entry(clique, bitmask, 0, 1) else: utils.append_function_entry(clique, bitmask, 0, 0) else: utils.append_function_entry(clique, bitmask, 0, prev_val) continue utils.append_function_entry(clique, bitmask, 0, prev_val) self.constrs['transition'].append(clique)
def add_init_states_cliques(self): vars_list = list(self.problem.variables) vars_vals_bitset = 0 for i, v in enumerate(vars_list): vars_vals_bitset |= (int(self.problem.variables[v]) << i) for k in range(self.num_futures): vars_indices = self.state_vars_to_indices(vars_list, k, 0) clique = MRFClique(vars_indices) for i in range(2**len(vars_list)): if i == vars_vals_bitset: clique.function_table.append(1) else: clique.function_table.append(INVALID_POTENTIAL_VAL) self.cliques['init_states'].append(clique) logger.info('added_init_states_cliques|#init_states_cliques={}' .format(len(self.cliques['init_states'])))
def set_elevator_closed_transition(self, k, h): for elevator in self.inst_params['elevators']: var_indices = [self.get_elevator_closed_state(elevator), self.get_elevator_closed_state(elevator), self.get_open_door_action(elevator, 'up'), self.get_open_door_action(elevator, 'down'), self.get_close_door_action(elevator)] var_indices[0] = self.var_to_idx[var_indices[0], k, h] var_indices[1:] = [self.var_to_idx[v, k, h - 1] for v in var_indices[1:]] clique = MRFClique(var_indices) for bitmask in range(2**len(var_indices)): if utils.is_set(bitmask, 1) and not utils.is_set(bitmask, 2) \ and not utils.is_set(bitmask, 3) and utils.is_set(bitmask, 4): utils.append_function_entry(clique, bitmask, 0, 1) else: utils.append_function_entry(clique, bitmask, 0, 0) self.constrs['transition'].append(clique)
def add_reward_cliques(self, reward_tree, tree_vars): assert(self.num_futures > 0 and self.problem.horizon > 0) var_indices = self.state_vars_to_indices(tree_vars, 0, 0) var_indices.append(self.get_reward_var_index(0, 0)) clique_proto = MRFClique(var_indices) clique_proto.generate_reward_function_table(reward_tree, tree_vars) self.cliques['reward'].append(clique_proto) for k in range(self.num_futures): for t in range(self.problem.horizon): if k == 0 and t == 0: continue var_indices = self.state_vars_to_indices(tree_vars, k, t) var_indices.append(self.get_reward_var_index(k, t)) clique = MRFClique(var_indices) clique.function_table = clique_proto.function_table self.cliques['reward'].append(clique)
def set_elevator_dir_up_transition(self, k, h): for elevator in self.inst_params['elevators']: var_indices = [self.get_elevator_dir_state(elevator, 'up'), self.get_elevator_dir_state(elevator, 'up'), self.get_open_door_action(elevator, 'up'), self.get_open_door_action(elevator, 'down')] var_indices[0] = self.var_to_idx[var_indices[0], k, h] var_indices[1:] = [self.var_to_idx[v, k, h - 1] for v in var_indices[1:]] clique = MRFClique(var_indices) for bitmask in range(2**len(var_indices)): if utils.is_set(bitmask, 2): utils.append_function_entry(clique, bitmask, 0, 1) continue if utils.is_set(bitmask, 3): utils.append_function_entry(clique, bitmask, 0, 0) continue val = 1 if utils.is_set(bitmask, 1) else 0 utils.append_function_entry(clique, bitmask, 0, val) self.constrs['transition'].append(clique)
def set_transition_constrs(self): self.constrs['transition'] = [] for k in range(self.num_futures): for h in range(1, self.problem.horizon): for v in self.problem.variables: # Clique: LSB{v(h), v(h-1)[, g(h-1)], move-*(h-1),..., n(h-1),...}MSB x, y = self.get_coords_from_state(v) var_indices = [ self.var_to_idx[(v, k, h)], self.var_to_idx[(v, k, h - 1)] ] if v != self.goal: var_indices.append(self.var_to_idx[(self.goal, k, h - 1)]) action_to_bit_idx = {} action_bit_idx_start = len(var_indices) move_away_actions = self.grid[x].keys( ) + self.grid[y].keys() for action in move_away_actions: if action in action_to_bit_idx: continue action_to_bit_idx[action] = len(var_indices) var_indices.append(self.var_to_idx[(action, k, h - 1)]) action_to_bit_idx[self.opposite_action[action]] = len( var_indices) var_indices.append( self.var_to_idx[(self.opposite_action[action], k, h - 1)]) neighbor_info = {} # {n: (action to reach v from n, idx)} neighbor_bit_idx_start = len(var_indices) for action in self.grid[x]: nx, ny = self.grid[x][action], y n = self.get_state_from_coords(nx, ny) neighbor_info[n] = ( action_to_bit_idx[self.opposite_action[action]], len(var_indices)) var_indices.append(self.var_to_idx[(n, k, h - 1)]) for action in self.grid[y]: nx, ny = x, self.grid[y][action] n = self.get_state_from_coords(nx, ny) neighbor_info[n] = ( action_to_bit_idx[self.opposite_action[action]], len(var_indices)) var_indices.append(self.var_to_idx[(n, k, h - 1)]) clique = MRFClique(var_indices) for clique_bitmask in range(2**len(var_indices)): # Concurrency constraints num_set_action = utils.count_set_bit( clique_bitmask, action_bit_idx_start, neighbor_bit_idx_start) if num_set_action > self.problem.max_concurrency: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL_2) continue # At most 1 state is set num_set_state = utils.count_set_bit( clique_bitmask, neighbor_bit_idx_start, len(var_indices)) num_set_state += 1 if clique_bitmask & 2 != 0 else 0 num_set_state += 1 if v != self.goal and clique_bitmask & 4 != 0 else 0 if num_set_state > 1: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL_2) continue # If at goal, stays at goal if v == self.goal and clique_bitmask & 2 != 0: if clique_bitmask & 1 != 0: clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) continue if clique_bitmask & 4 != 0: if clique_bitmask & 1 != 0: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) else: clique.function_table.append(1) continue # Move to neighbors if clique_bitmask & 2 != 0: set_func_table = False for action in move_away_actions: if clique_bitmask & ( 1 << action_to_bit_idx[action]) != 0: if clique_bitmask & 1 == 0: clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) set_func_table = True break if set_func_table: continue # Move from neighbors else: set_func_table = False for neighbor in neighbor_info: is_action_set = ( clique_bitmask & (1 << neighbor_info[neighbor][0])) != 0 is_at_neighbor = ( clique_bitmask & (1 << neighbor_info[neighbor][1])) != 0 if is_at_neighbor and is_action_set: if random.random( ) < self.get_disappear_prob(v): determinized_val = 0 else: determinized_val = 1 if (clique_bitmask & 1) == determinized_val: clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) set_func_table = True break if set_func_table: continue if (clique_bitmask & 1) == ((clique_bitmask >> 1) & 1): clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) self.constrs['transition'].append(clique) logger.info('set_transition_constraints')
def set_transition_constrs(self): """ Each logical expression used to specify the transition function corresponds to a clique and an additional variable. If an entry in a clique is sufficient to decide the outcome of the next state or the outcome is already decided by earlier clauses, its extended variable is constrained to 1. Otherwise, it's constrained to 0. :return: """ self.constrs['transition'] = [] for k in range(self.num_futures): for h in range(1, self.problem.horizon): for v in self.problem.variables: # If at goal stays at goal clique = MRFClique([]) goal_ext_var = self.get_ext_variables('goal') if v == self.goal: clique.vars = [ self.var_to_idx[(v, k, h)], self.var_to_idx[(v, k, h - 1)], self.add_var((goal_ext_var, k, h)) ] for bitmask in range(2**len(clique.vars)): if utils.is_set(bitmask, 1): if not utils.is_set(bitmask, 2): clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) continue if utils.is_set(bitmask, 0): clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) else: clique.vars = [ self.var_to_idx[(v, k, h)], self.var_to_idx[(self.goal, k, h - 1)], self.add_var((goal_ext_var, k, h)) ] for bitmask in range(2**len(clique.vars)): if utils.is_set(bitmask, 1): if not utils.is_set(bitmask, 2): clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) continue if utils.is_set(bitmask, 0): clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) else: clique.function_table.append(1) self.constrs['transition'].append(clique) x, y = self.get_coords_from_state(v) all_actions = self.grid[x].keys() + self.grid[y].keys() # Moving to neighbours prev_ext_var = goal_ext_var for level, action in enumerate(all_actions): cur_ext_var = self.get_ext_variables('moveto', level) cur_ext_var_idx = self.add_var((cur_ext_var, k, h)) clique = MRFClique([ self.var_to_idx[(v, k, h)], self.var_to_idx[(v, k, h - 1)], self.var_to_idx[(action, k, h - 1)], self.var_to_idx[(prev_ext_var, k, h)], cur_ext_var_idx ]) for bitmask in range(2**len(clique.vars)): if utils.is_set(bitmask, 3): if utils.is_set(bitmask, 4): clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) continue if utils.is_set(bitmask, 1) and utils.is_set( bitmask, 2): if not utils.is_set(bitmask, 4): clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) continue if utils.is_set(bitmask, 0): clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) else: clique.function_table.append(1) prev_ext_var = self.get_ext_variables('moveto', level) self.constrs['transition'].append(clique) # Moving from neighbours for level, action in enumerate(all_actions): cur_ext_var = self.get_ext_variables('movefrom', level) cur_ext_var_idx = self.add_var((cur_ext_var, k, h)) neighbour_action = self.opposite_action[action] nx, ny = x, y if action in self.grid[x]: nx = self.grid[x][action] else: ny = self.grid[y][action] neighbour = self.get_state_from_coords(nx, ny) clique = MRFClique([ self.var_to_idx[(v, k, h)], self.var_to_idx[(neighbour, k, h - 1)], self.var_to_idx[(neighbour_action, k, h - 1)], self.var_to_idx[(prev_ext_var, k, h)], cur_ext_var_idx ]) for bitmask in range(2**len(clique.vars)): if utils.is_set(bitmask, 3): if utils.is_set(bitmask, 4): clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) continue if utils.is_set(bitmask, 1) and utils.is_set( bitmask, 2): if not utils.is_set(bitmask, 4): clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) continue if random.random() < self.get_disappear_prob( v): determinized_val = 0 else: determinized_val = 1 if utils.is_set(bitmask, 0) == (determinized_val == 1): clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) prev_ext_var = self.get_ext_variables('moveto', level) self.constrs['transition'].append(clique) # Otherwise keeps the same state clique = MRFClique([ self.var_to_idx[(v, k, h)], self.var_to_idx[(v, k, h - 1)], self.var_to_idx[(prev_ext_var, k, h)] ]) for bitmask in range(2**len(clique.vars)): if utils.is_set(bitmask, 2): clique.function_table.append(1) continue if utils.is_set(bitmask, 0) == utils.is_set(bitmask, 1): clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) self.constrs['transition'].append(clique) logger.info('set_transition_constraints')
def set_transition_constrs(self): self.constrs['transition'] = [] for k in range(self.num_futures): for h in range(1, self.problem.horizon): for v in self.problem.variables: # Clique: MSB[n1(h-1), n2(h-1),..., v(h-1), v(h), reboot(v, h-1)]LSB neighbours = self.topology[v] var_indices = [ self.var_to_idx[(self.find_matching_action(v), k, h - 1)], self.var_to_idx[(v, k, h)], self.var_to_idx[(v, k, h - 1)] ] var_indices.extend( [self.var_to_idx[(n, k, h - 1)] for n in neighbours]) num_vars = len(var_indices) determinized_transition = {} clique = MRFClique(var_indices) clique.function_table = [] for clique_bitmask in range(2**num_vars): if clique_bitmask & 1 != 0: if clique_bitmask & 2 != 0: clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) else: dependencies_bitmask = clique_bitmask >> 2 if dependencies_bitmask in determinized_transition: determinized_val = determinized_transition[ dependencies_bitmask] else: if clique_bitmask & 4 != 0: running_neighbours = self.count_set_neighbours( clique_bitmask, len(neighbours)) running_prob = 0.45 + 0.5 * ( 1 + running_neighbours) / ( 1 + len(neighbours)) if random.random() <= running_prob: determinized_val = 1 else: determinized_val = 0 else: if random.random() <= self.REBOOT_PROB: determinized_val = 1 else: determinized_val = 0 determinized_transition[ dependencies_bitmask] = determinized_val if (clique_bitmask & 2) >> 1 == determinized_val: clique.function_table.append(1) else: clique.function_table.append( mrf.INVALID_POTENTIAL_VAL) self.constrs['transition'].append(clique) logger.info('set_transition_constraints')
def set_person_in_elevator_transition(self, k, h): for elevator in self.inst_params['elevators']: person_in_elevator_going_up = self.get_person_in_elevator_state(elevator, 'up') person_in_elevator_going_down = self.get_person_in_elevator_state(elevator, 'down') elevator_closed = self.get_elevator_closed_state(elevator) elevator_dir_up = self.get_elevator_dir_state(elevator, 'up') elevator_at_floor = [self.get_elevator_at_state(elevator, floor) for floor in self.inst_params['floors']] person_waiting_up = [self.get_person_waiting_state(floor, 'up') for floor in self.inst_params['floors']] person_waiting_down = [self.get_person_waiting_state(floor, 'down') for floor in self.inst_params['floors']] floor_offset = 4 waiting_offset = floor_offset + len(elevator_at_floor) common_indices = [(elevator_closed, k, h - 1), (elevator_dir_up, k, h - 1)] common_indices += [(v, k, h - 1) for v in elevator_at_floor] # Going up var_indices = [(person_in_elevator_going_up, k, h), (person_in_elevator_going_up, k, h - 1)] var_indices += common_indices + [(v, k, h - 1) for v in person_waiting_up] var_indices = [self.var_to_idx[v] for v in var_indices] elevator_at_top_floor_idx = 4 + self.inst_params['TOP-FLOOR'] clique = MRFClique(var_indices) for bitmask in range(2**len(var_indices)): if utils.is_set(bitmask, 1): if utils.is_set(bitmask, elevator_at_top_floor_idx): utils.append_function_entry(clique, bitmask, 0, 0) else: utils.append_function_entry(clique, bitmask, 0, 1) continue if utils.is_set(bitmask, 2): utils.append_function_entry(clique, bitmask, 0, 0) continue if not utils.is_set(bitmask, 3): utils.append_function_entry(clique, bitmask, 0, 0) continue done = False for i in range(len(elevator_at_floor)): if utils.is_set(bitmask, floor_offset + i) and utils.is_set(bitmask, waiting_offset + i): utils.append_function_entry(clique, bitmask, 0, 1) done = True break if not done: utils.append_function_entry(clique, bitmask, 0, 0) self.constrs['transition'].append(clique) # Going down var_indices = [(person_in_elevator_going_down, k, h), (person_in_elevator_going_down, k, h - 1)] var_indices += common_indices + [(v, k, h - 1) for v in person_waiting_down] var_indices = [self.var_to_idx[v] for v in var_indices] elevator_at_bottom_floor_idx = 4 + self.inst_params['BOTTOM-FLOOR'] clique = MRFClique(var_indices) for bitmask in range(2**len(var_indices)): if utils.is_set(bitmask, 1): if utils.is_set(bitmask, elevator_at_bottom_floor_idx): utils.append_function_entry(clique, bitmask, 0, 0) else: utils.append_function_entry(clique, bitmask, 0, 1) continue if utils.is_set(bitmask, 2): utils.append_function_entry(clique, bitmask, 0, 0) continue if utils.is_set(bitmask, 3): utils.append_function_entry(clique, bitmask, 0, 0) continue done = False for i in range(len(elevator_at_floor)): if utils.is_set(bitmask, floor_offset + i) and utils.is_set(bitmask, waiting_offset + i): utils.append_function_entry(clique, bitmask, 0, 1) done = True break if not done: utils.append_function_entry(clique, bitmask, 0, 0) self.constrs['transition'].append(clique)