def __init__(self, G, max_res, min_res, preprocess, REF, algorithm=None): # Check inputs check(G, max_res, min_res, REF_forward=REF, algorithm=__name__) # Preprocess graph self.G = preprocess_graph(G, max_res, min_res, preprocess, REF) self.max_res = max_res self.min_res = min_res # Update resource extension function if given if REF: self.REF = REF else: self.REF = add if negative_edge_cycle(G) or algorithm == "simple": self.algorithm = "simple" else: self.algorithm = "astar" # Attribute to hold source-sink path self.st_path = None # Attribrutes for exposure # # resource feasible source-sink path self.best_path = None # Final cost self.best_path_cost = None # Final resource consumption self.best_path_total_res = None
def __init__( self, G: DiGraph, max_res: List[float], min_res: List[float], preprocess: Optional[bool] = False, direction: Optional[str] = "both", method: Optional[str] = "unprocessed", time_limit: Optional[Union[float, int]] = None, threshold: Optional[float] = None, elementary: Optional[bool] = False, bounds_pruning: Optional[bool] = False, find_critical_res: Optional[bool] = False, critical_res: Optional[int] = None, # seed: Union[int] = None, REF_callback: Optional[REFCallback] = None): # Check inputs check(G, max_res, min_res, direction, REF_callback, __name__) # check_seed(seed, __name__) # Preprocess and save graph self.G: DiGraph = preprocess_graph(G, max_res, min_res, preprocess, REF_callback) # Vertex id with source/sink self._source_id: int = None self._sink_id: int = None max_res_vector = _convert_list_to_double_vector(max_res) min_res_vector = _convert_list_to_double_vector(min_res) # Pass graph self._init_graph() self.bidirectional_cpp = BiDirectionalCpp(len(self.G.nodes()), len(self.G.edges()), self._source_id, self._sink_id, max_res_vector, min_res_vector) self._load_graph() # pass solving attributes if direction != "both": self.bidirectional_cpp.setDirection(direction) if method in ["random", "generated", "processed"]: self.bidirectional_cpp.setMethod(method) if time_limit is not None and isinstance(time_limit, (int, float)): self.bidirectional_cpp.setTimeLimit(time_limit) if threshold is not None and isinstance(time_limit, (int, float)): self.bidirectional_cpp.setThreshold(threshold) if isinstance(elementary, bool) and elementary: self.bidirectional_cpp.setElementary(True) if isinstance(bounds_pruning, bool) and not bounds_pruning: self.bidirectional_cpp.setBoundsPruning(bounds_pruning) if isinstance(find_critical_res, bool) and critical_res: self.bidirectional_cpp.setFindCriticalRes(True) if isinstance(critical_res, int) and critical_res != 0: self.bidirectional_cpp.setCriticalRes(critical_res) if REF_callback is not None: # Add a Python callback (caller owns the callback, so we # disown it first by calling __disown__). # see: https://github.com/swig/swig/blob/b6c2438d7d7aac5711376a106a156200b7ff1056/Examples/python/callback/runme.py#L36 self.bidirectional_cpp.setREFCallback(REF_callback.__disown__())
def __init__(self, G: DiGraph, max_res: List[float], min_res: List[float], preprocess: Optional[bool] = False, direction: Optional[str] = "both", method: Optional[str] = "random", time_limit: Optional[float] = None, threshold: Optional[float] = None, elementary: Optional[bool] = False, dominance_frequency: Optional[int] = 1, seed: Union[int, RandomState, None] = None, REF_forward: Optional[Callable] = None, REF_backward: Optional[Callable] = None, REF_join: Optional[Callable] = None): # Check inputs check(G, max_res, min_res, direction, REF_forward=REF_forward, REF_backward=REF_backward, REF_join=REF_join, algorithm=__name__) # Preprocess graph self.G = preprocess_graph(G, max_res, min_res, preprocess, REF_forward) self.max_res = max_res.copy() self.min_res = min_res.copy() self.max_res_in, self.min_res_in = array(max_res.copy()), array( min_res.copy()) self.direction = direction self.method = method self.time_limit = time_limit self.elementary = elementary self.threshold = threshold self.dominance_frequency = dominance_frequency self.random_state = check_seed(seed) # Set label class attributes Label.REF_forward = REF_forward if REF_forward else add Label.REF_backward = REF_backward if REF_backward else sub self.REF_join = REF_join # Algorithm specific attributes self.iteration = 0 # Containers for labels self.current_label: Dict[str, Label] = None self.unprocessed_labels: Dict[str, List[Label]] = None self.best_labels: Dict[str, List[Label]] = None # Containers for counters self.unprocessed_counts: Dict[str, int] = 0 self.processed_counts: Dict[str, int] = 0 self.generated_counts: Dict[str, int] = 0 # For exposure self.final_label: Label = None self.best_label: Label = None # Populate containers self._init_containers()
def __init__(self, G: DiGraph, max_res: List[float], min_res: List[float], preprocess: Optional[bool] = False, direction: Optional[str] = "both", method: Optional[str] = "unprocessed", time_limit: Optional[Union[float, int]] = None, threshold: Optional[float] = None, elementary: Optional[bool] = False, bounds_pruning: Optional[bool] = False, seed: Union[int] = None, REF_callback: Optional[REFCallback] = None): # Check inputs check(G, max_res, min_res, direction, REF_callback, __name__) # check_seed(seed, __name__) # Preprocess graph G = preprocess_graph(G, max_res, min_res, preprocess, REF_callback) # To save original node type (for conversion at the end) self._original_node_type: str = None max_res_vector = _convert_list_to_double_vector(max_res) min_res_vector = _convert_list_to_double_vector(min_res) self.bidirectional_cpp = BiDirectionalCpp(len(G.nodes()), len(G.edges()), max_res_vector, min_res_vector) # pass solving attributes if direction != "both": self.bidirectional_cpp.direction = direction if method in ["random", "generated", "processed"]: self.bidirectional_cpp.method = method if time_limit is not None and isinstance(time_limit, (int, float)): self.bidirectional_cpp.time_limit = time_limit if threshold is not None and isinstance(time_limit, (int, float)): self.bidirectional_cpp.threshold = threshold if isinstance(elementary, bool) and elementary: self.bidirectional_cpp.elementary = elementary if isinstance(bounds_pruning, bool) and not bounds_pruning: self.bidirectional_cpp.bounds_pruning = bounds_pruning if isinstance(seed, int) and seed is not None: self.bidirectional_cpp.setSeed(seed) if REF_callback is not None: # Add a Python callback (caller owns the callback, so we # disown it first by calling __disown__). # see: https://github.com/swig/swig/blob/b6c2438d7d7aac5711376a106a156200b7ff1056/Examples/python/callback/runme.py#L36 self.bidirectional_cpp.setREFCallback(REF_callback.__disown__()) # Pass graph self._init_graph(G)
def __init__(self, G, max_res, min_res, REF=None, preprocess=False): # Check inputs check(G, max_res, min_res, REF, algorithm=__name__) # Preprocess graph self.G = preprocess_graph(G, max_res, min_res, preprocess, REF) self.max_res = max_res self.min_res = min_res # Update resource extension function if given if REF: self.REF = REF else: self.REF = add # Attribute to hold source-sink path self.st_path = None # Attribrutes for exposure # # resource feasible source-sink path self.best_path = None # Final cost self.best_path_cost = None # Final resource consumption self.best_path_total_res = None
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 testUnreachable(self): """ Tests if the unreachable node 'B' is removed. """ self.G = preprocess_graph(self.G, [5, 20], [0, 0], True) self.assertTrue('B' not in self.G.nodes())
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))
def testFindBadNode(self): """ Tests if expensive node 'B' is removed """ self.F = preprocess_graph(self.F, [5], [1], True) self.assertTrue('B' not in self.F.nodes())