Beispiel #1
0
    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"))
Beispiel #3
0
    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
Beispiel #4
0
    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))
Beispiel #5
0
    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"))
Beispiel #6
0
 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"))
Beispiel #7
0
    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))