def apply_next_swaps(self, require_frontier_adjacency: bool = False): """Applies a few SWAPs to get the mapping closer to one in which the next logical gates can be applied. See route_circuit_greedily for more details. """ time_slices = get_time_slices(self.remaining_dag) if require_frontier_adjacency: frontier_edges = sorted(time_slices[0].edges) self.bring_farthest_pair_together(frontier_edges) return for k in range(1, self.max_search_radius + 1): candidate_swap_sets = list(self.get_edge_sets(k)) for time_slice in time_slices: edges = sorted(time_slice.edges) distance_vectors = list( self.get_distance_vector(edges, swap_set) for swap_set in candidate_swap_sets) dominated_indices = _get_dominated_indices(distance_vectors) candidate_swap_sets = [ S for i, S in enumerate(candidate_swap_sets) if i not in dominated_indices ] if len(candidate_swap_sets) == 1: self.apply_swap(*candidate_swap_sets[0]) return self.apply_next_swaps(True)
def set_initial_mapping(self, initial_mapping: Optional[Dict[ops.Qid, ops.Qid]] = None): """Sets the internal state according to an initial mapping. Args: initial_mapping: The mapping to use. If not given, one is found greedily. """ if initial_mapping is None: time_slices = get_time_slices(self.remaining_dag) if not time_slices: initial_mapping = dict( zip(self.device_graph, self.logical_qubits)) else: logical_graph = time_slices[0] logical_graph.add_nodes_from(self.logical_qubits) initial_mapping = get_initial_mapping(logical_graph, self.device_graph, self.prng) self.initial_mapping = initial_mapping self._phys_to_log = { q: initial_mapping.get(q) for q in self.physical_qubits } self._log_to_phys = { l: p for p, l in self._phys_to_log.items() if l is not None } self._assert_mapping_consistency()