def _init_containers(self): 'Initialise containers (labels and counters)' # set minimum bounds if not all 0 if any(m != 0 for m in self.min_res): self.min_res = zeros(len(self.min_res)) bwd_start = self.min_res.copy() bwd_start[0] = self.max_res[0] self.current_label = OrderedDict({ "forward": Label(0, "Source", self.min_res, ["Source"]), "backward": Label(0, "Sink", bwd_start, ["Sink"]) }) self.unprocessed_labels = OrderedDict({ "forward": deque(), "backward": deque() }) # Best labels self.best_labels = OrderedDict({ "forward": deque([self.current_label["forward"]]), "backward": deque([self.current_label["backward"]]) }) # Counters self.unprocessed_counts = OrderedDict({"forward": 0, "backward": 0}) self.processed_counts = OrderedDict({"forward": 0, "backward": 0}) self.generated_counts = OrderedDict({"forward": 0, "backward": 0})
def testDominance(self): # Check forward and backward label dominance L1 = Label(10, 'B', array([6, 5]), []) L2 = Label(1, 'B', array([6, -3]), []) L3 = Label(-10, 'A', array([3, -8]), []) L4 = Label(-10, 'A', array([4, -6]), []) self.assertTrue(L2.dominates(L1, "forward")) self.assertTrue(L3.dominates(L4, "forward"))
def _merge_labels(self, fwd_label, bwd_label): """ Merge labels produced by a backward and forward label. Paramaters ---------- fwd_label : label.Label object bwd_label : label.Label object Returns ------- merged_label : label.Label object If an s-t compatible path can be obtained the appropriately extended and merged label is returned None Otherwise. """ # Make a copy of the backward label _bwd_label = deepcopy(bwd_label) # Reconstruct edge with edge data edge = (fwd_label.node, _bwd_label.node, self.G[fwd_label.node][_bwd_label.node]) # Custom resource merging function if self.REF_join: final_res = self.REF_join(fwd_label.res, _bwd_label.res, edge) self._process_bwd_label(_bwd_label, self.min_res_in) # Default resource merging else: # Extend forward label along joining edge label = fwd_label.get_new_label(edge, "forward") if not label: return # Process backward label self._process_bwd_label(_bwd_label, label.res) final_res = _bwd_label.res # Record total weight, total_res and final path weight = fwd_label.weight + edge[2]['weight'] + _bwd_label.weight final_path = fwd_label.path + _bwd_label.path merged_label = Label(weight, "Sink", final_res, final_path) return merged_label
def __init__(self, G, max_res, min_res, preprocess=False, direction="both", method="random", seed=None, REF_forward=None, REF_backward=None, REF_join=None): # Check inputs check(G, max_res, min_res, REF_forward=REF_forward, REF_backward=REF_backward, REF_join=REF_join, direction=direction, algorithm=__name__) # Preprocess graph self.G = preprocess_graph(G, max_res, min_res, preprocess, REF_forward) self.REF_join = REF_join self.direc_in = direction self.max_res, self.min_res = max_res.copy(), min_res.copy() self.max_res_in, self.min_res_in = array(max_res.copy()), array( min_res.copy()) self.method = method # To expose results self.best_label = None # Algorithm specific parameters # # set bounds for bacward search bwd_start = deepcopy(min_res) bwd_start[0] = max_res[0] # Current forward and backward labels self.current_label = OrderedDict({ "forward": Label(0, "Source", min_res, ["Source"]), "backward": Label(0, "Sink", bwd_start, ["Sink"]) }) # Unprocessed labels dict (both directions) self.unprocessed_labels = OrderedDict({ "forward": deque(), "backward": deque() }) # All generated label self.generated_labels = OrderedDict({"forward": 0, "backward": 0}) # Best labels # (with initial labels for small cases, see: # https://github.com/torressa/cspy/issues/38 ) self.best_labels = OrderedDict({ "forward": deque([self.current_label["forward"]]), "backward": deque([self.current_label["backward"]]) }) # Final labels dicts for unidirectional search self.final_label = None # If given, set REFs for dominance relations and feasibility checks if REF_forward: Label._REF_forward = REF_forward else: Label._REF_forward = add if REF_backward: Label._REF_backward = REF_backward else: Label._REF_backward = sub # Init with seed if given if seed is None: self.random_state = RandomState() elif isinstance(seed, int): self.random_state = RandomState(seed) elif isinstance(seed, RandomState): self.random_state = seed else: raise Exception("{} cannot be used to seed".format(seed))
def test_dominance(self): # Check forward and backward label dominance L1 = Label(-10, "Sink", array([3, 0]), []) L2 = Label(0, "Sink", array([1, 0]), []) self.assertFalse(L1.dominates(L2, "forward")) self.assertFalse(L2.dominates(L1, "forward")) self.assertTrue(L1.dominates(L2, "backward")) self.assertFalse(L2.dominates(L1, "backward")) if not (L1.dominates(L2, "forward") or L2.dominates(L1, "forward")): self.assertTrue(L1.dominates(L2, "backward"))
def testDominance(self): # Check forward and backward label dominance L1 = Label(0, 1, array([1, 1]), []) L2 = Label(-1, 1, array([1, 1]), []) L3 = Label(-10, 2, array([1, 1]), []) L4 = Label(-10, 2, array([0, 1]), []) L5 = Label(0, 2, array([1, 1]), []) self.assertTrue(L2.dominates(L1, "forward")) self.assertRaises(Exception, L1.dominates, L3) self.assertFalse(L3.dominates(L4, "forward")) self.assertTrue(L4.dominates(L3, "forward")) self.assertTrue(L3.dominates(L5, "forward"))
def __init__(self, G, max_res, min_res, REF=None, preprocess=False, direction="both", method="random", seed=None): # Check inputs and preprocess G unless option disabled check(G, max_res, min_res, REF, direction, __name__) # Preprocess graph self.G = preprocess_graph(G, max_res, min_res, preprocess, REF) self.direc_in = direction self.max_res, self.min_res = max_res.copy(), min_res.copy() self.max_res_in, self.min_res_in = array(max_res.copy()), array( min_res.copy()) self.method = method # To expose results self.best_label = None # Algorithm specific parameters # # set bounds for bacward search bwd_start = deepcopy(min_res) bwd_start[0] = max_res[0] # Current forward and backward labels self.current_label = OrderedDict({ "forward": Label(0, "Source", min_res, ["Source"]), "backward": Label(0, "Sink", bwd_start, ["Sink"]) }) # Unprocessed labels dict (both directions) self.unprocessed_labels = OrderedDict({ "forward": deque(), "backward": deque() }) # All generated label self.generated_labels = OrderedDict({"forward": 0, "backward": 0}) # To save all best labels self.best_labels = OrderedDict({ "forward": deque(), "backward": deque() }) # Final labels dicts for unidirectional search self.final_label = None # If given, set REFs for dominance relations and feasibility checks if REF: Label._REF = REF else: Label._REF = add # Init with seed if given if seed is None: self.random_state = RandomState() elif isinstance(seed, int): self.random_state = RandomState(seed) elif isinstance(seed, RandomState): self.random_state = seed else: raise Exception("{} cannot be used to seed".format(seed))