def test_usage_maximize(self): q = WorstBoundFirstPriorityQueue(maximize) assert q.size() == 0 assert q.bound() is None assert len(list(q.items())) == 0 assert q.get() is None items = [] for i in range(1, 11): node = Node(size=0) node.bound = -i assert node.queue_priority is None cnt_ = q.put(node._data) assert cnt_ == i - 1 assert node.queue_priority == node.bound items.append(node._data) assert q.size() == i assert q.bound() == -1 _check_items(q, items) assert q.size() == 10 assert q.bound() == -1 removed = q.filter(lambda data: \ Node._extract_bound(data) <= -5) assert q.size() == 6 assert len(removed) == 4 for data in removed: assert Node._extract_bound(data) > -5 assert q.bound() == -5 for i in range(5, 11): node = Node(data_=q.get()) assert node.bound == -i assert node.queue_priority == node.bound if i != 10: assert q.bound() == -i - 1 else: assert q.bound() is None assert q.size() == 0 node = Node(size=0) node.bound = 1 assert node.queue_priority is None cnt_, data = q.put_get(node._data) assert cnt_ == 10 assert data is node._data assert node.queue_priority == 1 node.bound = 2 cnt_ = q.put(node._data) assert node.queue_priority == 2 assert cnt_ == 11 node2 = Node(size=0) node2.bound = 3 assert node2.queue_priority is None cnt_, data = q.put_get(node2._data) assert cnt_ == 12 assert data is node2._data assert node2.queue_priority == 3 node2.bound = 1 cnt_, data = q.put_get(node2._data) assert node2.queue_priority == 1 assert cnt_ == 13 assert data is node._data assert q.size() == 1
def test_overwrites_queue_priority(self): q = LIFOQueue(sense=minimize, track_bound=True) node = Node() node.tree_depth = 0 node.bound = 0 assert node.queue_priority is None assert q.put(node) == 0 assert node.queue_priority == 0 child = _new_child(node) assert child.queue_priority is None assert q.put(child) == 1 assert child.queue_priority == 1 l1 = Node() l1.tree_depth = 0 l1.bound = 1 l2 = _new_child(l1) l3 = _new_child(l2) q = LIFOQueue(sense=minimize, track_bound=True) cnt = q.put(l2) node_ = q.get() assert cnt == 0 assert node_ is l2 cnt = q.put(l2) assert q.bound() == 1 assert cnt == 1 cnt = q.put(l3) node_ = q.get() assert cnt == 2 assert node_ is l3 node_ = q.get() assert node_ is l2 assert q.bound() is None
def test_overwrites_queue_priority(self): q = FIFOQueue(minimize) node = Node(size=0) node.bound = 0 assert node.queue_priority is None assert q.put(node._data) == 0 assert node.queue_priority == 0 child = node.new_child() assert child.queue_priority is None assert q.put(child._data) == 1 assert child.queue_priority == -1 l1 = Node(size=0) l1.bound = 1 l2 = l1.new_child() l3 = l2.new_child() q = FIFOQueue(minimize) cnt, data = q.put_get(l2._data) assert cnt == 0 assert data is l2._data cnt = q.put(l2._data) assert cnt == 1 cnt, data_ = q.put_get(l3._data) assert cnt == 2 assert data_ is l2._data cnt, data_ = q.put_get(l1._data) assert cnt == 3 assert data_ is l3._data assert q.bound() == 1
def test_overwrites_queue_priority(self): q = DepthFirstPriorityQueue(minimize) node = Node(size=0) node.bound = 0 assert node.queue_priority is None assert q.put(node._data) == 0 assert node.tree_depth == 0 assert node.queue_priority == 0 child = node.new_child() assert child.tree_depth == 1 assert child.queue_priority is None assert q.put(child._data) == 1 assert child.queue_priority == child.tree_depth l1 = Node(size=0) l1.bound = 1 l2 = l1.new_child() l3 = l2.new_child() q = DepthFirstPriorityQueue(minimize) q.put(l2._data) cnt, data_ = q.put_get(l3._data) assert cnt == 1 assert data_ is l3._data cnt, data_ = q.put_get(l2._data) assert cnt == 2 assert data_ is l2._data assert q.bound() == 1
def test_overwrites_queue_priority(self): q = RandomPriorityQueue(minimize) node = Node(size=0) node.bound = 0 assert node.queue_priority is None assert q.put(node._data) == 0 assert node.queue_priority is not None assert 0 <= node.queue_priority <= 1 child = node.new_child() assert child.queue_priority is None assert q.put(child._data) == 1 assert child.queue_priority is not None assert 0 <= child.queue_priority <= 1 l1 = Node(size=0) l1.bound = 1 l2 = l1.new_child() l3 = l2.new_child() q = RandomPriorityQueue(minimize) assert l2.queue_priority is None cnt, data = q.put_get(l2._data) assert data is l2._data assert l2.queue_priority is not None assert 0 <= l2.queue_priority <= 1 assert cnt == 0 cnt = q.put(l2._data) assert cnt == 1 assert l3.queue_priority is None cnt, data_ = q.put_get(l3._data) assert cnt == 2 assert l3.queue_priority is not None assert 0 <= l3.queue_priority <= 1 assert data_ is max([l2, l3], key=lambda x_: x_.queue_priority)._data
def test_overwrites_queue_priority(self): q = BestObjectiveFirstPriorityQueue(sense=minimize, track_bound=True) node = Node() node.tree_depth = 0 node.bound = -1 assert node.queue_priority is None node.objective = 1 assert q.put(node) == 0 assert node.objective == 1 assert node.queue_priority == -1 child = _new_child(node) assert child.objective == 1 child.objective = 0 assert child.queue_priority is None cnt = q.put(child) node_ = q.get() assert child.queue_priority == 0 assert cnt == 1 assert node_ is child child.objective = 2 cnt = q.put(child) node_ = q.get() assert child.queue_priority == -2 assert cnt == 2 assert node_ is node assert q.bound() == -1 q = BestObjectiveFirstPriorityQueue(sense=maximize, track_bound=True) node = Node() node.tree_depth = 0 node.bound = 3 assert node.queue_priority is None node.objective = 1 assert q.put(node) == 0 assert node.objective == 1 assert node.queue_priority == 1 child = _new_child(node) assert child.objective == 1 child.objective = 2 assert child.queue_priority is None cnt = q.put(child) node_ = q.get() assert child.queue_priority == 2 assert cnt == 1 assert node_ is child child.objective = 0 cnt = q.put(child) node_ = q.get() assert child.queue_priority == 0 assert cnt == 2 assert node_ is node assert q.bound() == 3
def test_overwrites_queue_priority(self): q = WorstBoundFirstPriorityQueue(sense=minimize, track_bound=True) node = Node() node.bound = 1 assert node.queue_priority is None q.put(node) assert node.queue_priority == -1 q = WorstBoundFirstPriorityQueue(sense=maximize, track_bound=True) node = Node() node.bound = 1 assert node.queue_priority is None q.put(node) assert node.queue_priority == 1
def test_overwrites_queue_priority(self): q = WorstBoundFirstPriorityQueue(minimize) node = Node(size=0) node.bound = 1 assert node.queue_priority is None q.put(node._data) assert node.queue_priority == -1 q = WorstBoundFirstPriorityQueue(maximize) node = Node(size=0) node.bound = 1 assert node.queue_priority is None q.put(node._data) assert node.queue_priority == 1
def test_initialize_queue(self): node_limit = None time_limit = None log = get_simple_logger() log_interval_seconds = inf log_new_incumbent = True convergence_checker = ConvergenceChecker(minimize) root = Node(size=0) Node._insert_tree_id(root._data, 0) root.bound = convergence_checker.unbounded_objective root.objective = convergence_checker.infeasible_objective queue = DispatcherQueueData(nodes=[root], next_tree_id=1) disp = DispatcherLocal() disp.initialize(0, queue, 'bound', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert disp.best_objective == 0 disp.initialize(1, queue, 'bound', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert disp.best_objective == 1 root.objective = -1 disp.initialize(1, queue, 'bound', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert disp.best_objective == -1
def _logging_redirect_check(comm): opt = Solver(comm=comm) p = DummyProblem() log = logging.Logger(None, level=logging.WARNING) log.addHandler(_RedirectHandler(opt._disp)) if opt.is_dispatcher: assert (comm is None) or (comm.rank == 0) root = Node() p.save_state(root) root.objective = p.infeasible_objective() root.bound = p.unbounded_objective() initialize_queue = DispatcherQueueData(nodes=[root], worst_terminal_bound=None, sense=p.sense()) out = StringIO() formatter = logging.Formatter("[%(levelname)s] %(message)s") opt._disp.initialize( p.infeasible_objective(), None, initialize_queue, "bound", ConvergenceChecker(p.sense()), None, None, None, True, get_simple_logger(console=True, stream=out, level=logging.DEBUG, formatter=formatter), 0.0, True, ) log.debug("0: debug") log.info("0: info") log.warning("0: warning") log.error("0: error") log.critical("0: critical") if (comm is not None) and (comm.size > 1): opt._disp.serve() else: assert comm is not None if comm.size > 1: for i in range(1, comm.size): if comm.rank == i: log.debug(str(comm.rank) + ": debug") log.info(str(comm.rank) + ": info") log.warning(str(comm.rank) + ": warning") log.error(str(comm.rank) + ": error") log.critical(str(comm.rank) + ": critical") opt.worker_comm.Barrier() if opt.worker_comm.rank == 0: opt._disp.stop_listen() if comm is not None: comm.Barrier() if opt.is_dispatcher: assert ("\n".join( out.getvalue().splitlines()[7:])) == _get_logging_baseline( comm.size if comm is not None else 1)
def _new_child(node): child = Node() child.objective = node.objective child.bound = node.bound child.tree_depth = node.tree_depth + 1 assert child.queue_priority is None assert child.state is None return child
def test_overwrites_queue_priority(self): q = BestObjectiveFirstPriorityQueue(minimize) node = Node(size=0) node.bound = -1 assert node.queue_priority is None node.objective = 1 assert q.put(node._data) == 0 assert node.objective == 1 assert node.queue_priority == -1 child = node.new_child() assert child.objective == 1 child.objective = 0 assert child.queue_priority is None cnt, data_ = q.put_get(child._data) assert child.queue_priority == 0 assert cnt == 1 assert data_ is child._data child.objective = 2 cnt, data_ = q.put_get(child._data) assert child.queue_priority == -2 assert cnt == 2 assert data_ is node._data assert q.bound() == -1 q = BestObjectiveFirstPriorityQueue(maximize) node = Node(size=0) node.bound = 3 assert node.queue_priority is None node.objective = 1 assert q.put(node._data) == 0 assert node.objective == 1 assert node.queue_priority == 1 child = node.new_child() assert child.objective == 1 child.objective = 2 assert child.queue_priority is None cnt, data_ = q.put_get(child._data) assert child.queue_priority == 2 assert cnt == 1 assert data_ is child._data child.objective = 0 cnt, data_ = q.put_get(child._data) assert child.queue_priority == 0 assert cnt == 2 assert data_ is node._data assert q.bound() == 3
def test_str(self): node = Node() node.objective = -1 node.bound = -2 node.tree_depth = 3 node.queue_priority = (1,2,3) node.state = 'a' assert str(node) == \ """\
def test_str(self): node = Node() node.objective = -1 node.bound = -2 node.tree_depth = 3 node.queue_priority = (1, 2, 3) node.state = "a" assert (str(node) == """\ Node(objective=-1, bound=-2, tree_depth=3)""")
def test_overwrites_queue_priority(self): q = RandomPriorityQueue(sense=minimize, track_bound=True) node = Node() node.tree_depth = 0 node.bound = 0 assert node.queue_priority is None assert q.put(node) == 0 assert node.queue_priority is not None assert 0 <= node.queue_priority <= 1 child = _new_child(node) assert child.queue_priority is None assert q.put(child) == 1 assert child.queue_priority is not None assert 0 <= child.queue_priority <= 1 l1 = Node() l1.tree_depth = 0 l1.bound = 1 l2 = _new_child(l1) l3 = _new_child(l2) q = RandomPriorityQueue(sense=minimize, track_bound=True) assert l2.queue_priority is None cnt = q.put(l2) node_ = q.get() assert node_ is l2 assert l2.queue_priority is not None assert 0 <= l2.queue_priority <= 1 assert cnt == 0 cnt = q.put(l2) assert cnt == 1 assert l3.queue_priority is None cnt = q.put(l3) node_ = q.get() assert cnt == 2 assert l3.queue_priority is not None assert 0 <= l3.queue_priority <= 1 assert node_ is max([l2, l3], key=lambda x_: x_.queue_priority)
def test_missing_queue_priority(self): q = CustomPriorityQueue(sense=minimize, track_bound=True) node = Node() node.tree_depth = 0 node.bound = 0 assert node.queue_priority is None with pytest.raises(ValueError): q.put(node) node.queue_priority = 1 q.put(node) child = _new_child(node) assert child.queue_priority is None with pytest.raises(ValueError): q.put(child)
def test_queue_strategy(self): node_limit = None time_limit = None log = get_simple_logger() log_interval_seconds = inf log_new_incumbent = True convergence_checker = ConvergenceChecker(minimize) root = Node(size=0) Node._insert_tree_id(root._data, 0) root.bound = convergence_checker.unbounded_objective root.objective = convergence_checker.infeasible_objective queue = DispatcherQueueData(nodes=[root], next_tree_id=1) disp = DispatcherLocal() disp.initialize(inf, queue, 'bound', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is WorstBoundFirstPriorityQueue disp.initialize(inf, queue, 'custom', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is CustomPriorityQueue disp.initialize(inf, queue, 'objective', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is BestObjectiveFirstPriorityQueue disp.initialize(inf, queue, 'breadth', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is BreadthFirstPriorityQueue disp.initialize(inf, queue, 'depth', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is DepthFirstPriorityQueue disp.initialize(inf, queue, 'fifo', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is FIFOQueue disp.initialize(inf, queue, 'random', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is RandomPriorityQueue disp.initialize(inf, queue, 'local_gap', convergence_checker, node_limit, time_limit, log, log_interval_seconds, log_new_incumbent) assert type(disp.queue) is LocalGapPriorityQueue
def test_missing_queue_priority(self): q = CustomPriorityQueue(minimize) node = Node(size=0) node.bound = 0 assert node.queue_priority is None with pytest.raises(ValueError): q.put(node._data) with pytest.raises(ValueError): q.put_get(node._data) node.queue_priority = 1 q.put(node._data) child = node.new_child() assert child.queue_priority is None with pytest.raises(ValueError): q.put(child._data) with pytest.raises(ValueError): q.put_get(child._data)
def _logging_check(comm): opt = Solver(comm=comm) p = DummyProblem() if opt.is_dispatcher: assert (comm is None) or (comm.rank == 0) root = Node() p.save_state(root) root.objective = p.infeasible_objective() root.bound = p.unbounded_objective() assert root.tree_id is None Node._insert_tree_id(root._data, 0) initialize_queue = DispatcherQueueData(nodes=[root], next_tree_id=1) out = StringIO() formatter = logging.Formatter("[%(levelname)s] %(message)s") opt._disp.initialize( p.infeasible_objective(), initialize_queue, "bound", ConvergenceChecker(p.sense()), None, None, get_simple_logger(console=True, stream=out, level=logging.DEBUG, formatter=formatter), 0.0, True) opt._disp.log_debug("0: debug") opt._disp.log_info("0: info") opt._disp.log_warning("0: warning") opt._disp.log_error("0: error") if (comm is not None) and (comm.size > 1): opt._disp.serve() else: assert comm is not None if comm.size > 1: for i in range(1, comm.size): if comm.rank == i: opt._disp.log_debug(str(comm.rank) + ": debug") opt._disp.log_info(str(comm.rank) + ": info") opt._disp.log_warning(str(comm.rank) + ": warning") opt._disp.log_error(str(comm.rank) + ": error") opt.worker_comm.Barrier() if opt.worker_comm.rank == 0: opt._disp.stop_listen() if comm is not None: comm.Barrier() if opt.is_dispatcher: assert ('\n'.join(out.getvalue().splitlines()[8:])) == \ _get_logging_baseline(comm.size if comm is not None else 1)
def test_serialization(self): node = Node() node.objective = 0.0 node.bound = 1.0 node.tree_depth = -1 node.queue_priority = (1, 2, 3) node._uuid = None node.state = "a" s = _SerializedNode.from_node(node) assert s.objective == node.objective assert s.bound == node.bound assert s.tree_depth == node.tree_depth assert s.queue_priority == node.queue_priority assert s._uuid is None assert s.data is not None s._generate_uuid() assert s._uuid is not None node_ = s.restore_node(s.slots) assert node_.objective == node.objective assert node_.bound == node.bound assert node_.tree_depth == node.tree_depth assert node_.queue_priority == node.queue_priority assert node_.state == node.state assert node_._uuid == s._uuid
def test_new_child(self): node = Node() assert node.objective is None assert node.bound is None assert node.tree_depth is None assert node.queue_priority is None assert node.state is None node.tree_depth = 0 node = node.new_child() assert node.objective is None assert node.bound is None assert node.tree_depth == 1 assert node.queue_priority is None assert node.state is None node.objective = 1 node.bound = -1 node.queue_priority = 5 node.state = "a" node = node.new_child() assert node.objective == 1 assert node.bound == -1 assert node.tree_depth == 2 assert node.queue_priority is None assert node.state is None
def test_children(self): parent = Node() assert parent.queue_priority is None assert parent.tree_id is None assert parent.parent_tree_id is None assert parent.tree_depth == 0 assert len(parent.state) == 0 parent.queue_priority = 10 assert parent.queue_priority == 10 assert parent.tree_id is None assert parent.parent_tree_id is None assert parent.tree_depth == 0 assert len(parent.state) == 0 parent.bound = -1 assert parent.queue_priority == 10 assert parent.tree_id is None assert parent.parent_tree_id is None assert parent.tree_depth == 0 assert parent.bound == -1 parent.objective = -2 assert parent.queue_priority == 10 assert parent.tree_id is None assert parent.parent_tree_id is None assert parent.tree_depth == 0 assert parent.bound == -1 assert parent.objective == -2 assert len(parent.state) == 0 parent.resize(5) assert parent.queue_priority == 10 assert parent.tree_id is None assert parent.parent_tree_id is None assert parent.tree_depth == 0 assert parent.bound == -1 assert parent.objective == -2 assert len(parent.state) == 5 children = [parent.new_child() for i in range(3)] assert len(children) == 3 for child in children: assert child.queue_priority is None assert child.tree_id is None assert child.parent_tree_id is None assert child.tree_depth == 1 assert child.bound == -1 assert child.objective == -2 assert len(child.state) == 5 Node._insert_tree_id(parent._data, 0) assert parent.tree_id == 0 children = [parent.new_child() for i in range(3)] assert len(children) == 3 for child in children: assert child.queue_priority is None assert child.tree_id is None assert child.parent_tree_id == 0 assert child.tree_depth == 1 assert child.bound == -1 assert child.objective == -2 assert len(child.state) == 5 children = [parent.new_child(size=10) for i in range(4)] assert len(children) == 4 for child in children: assert child.queue_priority is None assert child.tree_id is None assert child.parent_tree_id == 0 assert child.tree_depth == 1 assert child.bound == -1 assert child.objective == -2 assert len(child.state) == 10
def test_overwrites_queue_priority(self): q = LocalGapPriorityQueue(minimize) node = Node(size=0) node.bound = -inf node.objective = inf assert node.queue_priority is None assert q.put(node._data) == 0 assert node.queue_priority is not None assert node.queue_priority == inf child = node.new_child() assert child.bound == -inf assert child.objective == inf child.bound = 0 assert child.queue_priority is None assert q.put(child._data) == 1 assert child.queue_priority is not None assert child.queue_priority == inf child = child.new_child() assert child.bound == 0 assert child.objective == inf child.objective = 1 assert child.queue_priority is None assert q.put(child._data) == 2 assert child.queue_priority is not None assert child.queue_priority == 1 l1 = Node(size=0) l1.bound = 1 l1.objective = 5 l2 = l1.new_child() l3 = l2.new_child() q = LocalGapPriorityQueue(minimize) assert l2.queue_priority is None cnt, data = q.put_get(l2._data) assert data is l2._data assert l2.queue_priority is not None assert l2.queue_priority == 4 assert cnt == 0 cnt = q.put(l2._data) assert cnt == 1 assert l3.queue_priority is None l3.objective = 6 cnt, data_ = q.put_get(l3._data) assert cnt == 2 assert l3.queue_priority is not None assert l3.queue_priority == 5 assert data_ is l3._data q = LocalGapPriorityQueue(maximize) node = Node(size=0) node.bound = inf node.objective = -inf assert node.queue_priority is None assert q.put(node._data) == 0 assert node.queue_priority is not None assert node.queue_priority == inf child = node.new_child() assert child.bound == inf assert child.objective == -inf child.bound = 0 assert child.queue_priority is None assert q.put(child._data) == 1 assert child.queue_priority is not None assert child.queue_priority == inf child = child.new_child() assert child.bound == 0 assert child.objective == -inf child.objective = -1 assert child.queue_priority is None assert q.put(child._data) == 2 assert child.queue_priority is not None assert child.queue_priority == 1 l1 = Node(size=0) l1.bound = -1 l1.objective = -5 l2 = l1.new_child() l3 = l2.new_child() q = LocalGapPriorityQueue(maximize) assert l2.queue_priority is None cnt, data = q.put_get(l2._data) assert data is l2._data assert l2.queue_priority is not None assert l2.queue_priority == 4 assert cnt == 0 cnt = q.put(l2._data) assert cnt == 1 assert l3.queue_priority is None l3.objective = -6 cnt, data_ = q.put_get(l3._data) assert cnt == 2 assert l3.queue_priority is not None assert l3.queue_priority == 5 assert data_ is l3._data
def test_overwrites_queue_priority(self): # min q = LexicographicPriorityQueue( (WorstBoundFirstPriorityQueue, BestObjectiveFirstPriorityQueue), minimize, True, ) node = Node() node.tree_depth = 0 node.bound = 0 node.objective = 2 assert node.queue_priority is None assert q.put(node) == 0 assert node.queue_priority is not None assert node.queue_priority == (0, -2) c1 = child = _new_child(node) assert child.bound == 0 assert child.objective == 2 child.objective = 1 assert child.queue_priority is None assert q.put(child) == 1 assert child.queue_priority is not None assert child.queue_priority == (0, -1) c2 = child = _new_child(child) assert child.bound == 0 assert child.objective == 1 child.bound = -1 child.objective = 2 assert child.queue_priority is None assert q.put(child) == 2 assert child.queue_priority is not None assert child.queue_priority == (1, -2) c3 = child = _new_child(child) assert child.bound == -1 assert child.objective == 2 child.bound = 1 child.objective = -100 assert child.queue_priority is None assert q.put(child) == 3 assert child.queue_priority is not None assert child.queue_priority == (-1, 100) assert q.get() is c2 assert q.get() is c1 assert q.get() is node assert q.get() is c3 assert q.get() is None # max q = LexicographicPriorityQueue( (WorstBoundFirstPriorityQueue, BestObjectiveFirstPriorityQueue), maximize, True, ) node = Node() node.tree_depth = 0 node.bound = 0 node.objective = -2 assert node.queue_priority is None assert q.put(node) == 0 assert node.queue_priority is not None assert node.queue_priority == (0, -2) c1 = child = _new_child(node) assert child.bound == 0 assert child.objective == -2 child.objective = -1 assert child.queue_priority is None assert q.put(child) == 1 assert child.queue_priority is not None assert child.queue_priority == (0, -1) c2 = child = _new_child(child) assert child.bound == 0 assert child.objective == -1 child.bound = 1 child.objective = -2 assert child.queue_priority is None assert q.put(child) == 2 assert child.queue_priority is not None assert child.queue_priority == (1, -2) c3 = child = _new_child(child) assert child.bound == 1 assert child.objective == -2 child.bound = -1 child.objective = 100 assert child.queue_priority is None assert q.put(child) == 3 assert child.queue_priority is not None assert child.queue_priority == (-1, 100) assert q.get() is c2 assert q.get() is c1 assert q.get() is node assert q.get() is c3 assert q.get() is None
def test_usage_maximize(self): q = WorstBoundFirstPriorityQueue(sense=maximize, track_bound=True) assert q.size() == 0 assert q.bound() is None assert len(list(q.items())) == 0 assert q.get() is None items = [] for i in range(1, 11): node = Node() node.bound = -i assert node.queue_priority is None cnt_ = q.put(node) assert cnt_ == i - 1 assert node.queue_priority == node.bound items.append(node) assert q.size() == i assert q.bound() == -1 _check_items(q, items) assert q.size() == 10 assert q.bound() == -1 removed = q.filter(lambda n_: n_.bound <= -5) assert q.size() == 6 assert len(removed) == 4 for node_ in removed: assert node_.bound > -5 assert q.bound() == -5 for i in range(5, 11): node = q.get() assert node.bound == -i assert node.queue_priority == node.bound if i != 10: assert q.bound() == -i - 1 else: assert q.bound() is None assert q.size() == 0 node = Node() node.bound = 1 assert node.queue_priority is None cnt_ = q.put(node) node_ = q.get() assert cnt_ == 10 assert node_ is node assert node.queue_priority == 1 node.bound = 2 cnt_ = q.put(node) assert node.queue_priority == 2 assert cnt_ == 11 node2 = Node() node2.bound = 3 assert node2.queue_priority is None cnt_ = q.put(node2) node_ = q.get() assert cnt_ == 12 assert node_ is node2 assert node2.queue_priority == 3 node2.bound = 1 cnt_ = q.put(node2) node_ = q.get() assert node2.queue_priority == 1 assert cnt_ == 13 assert node_ is node assert q.size() == 1
def test_usage_minimize(self): q = CustomPriorityQueue(minimize) assert q.size() == 0 assert q.bound() is None assert len(list(q.items())) == 0 assert q.get() is None items = [] for i in range(1, 11): node = Node(size=0) node.bound = i node.queue_priority = -i assert q.put(node._data) == i - 1 assert node.queue_priority == -i items.append(node._data) assert q.size() == i assert q.bound() == 1 _check_items(q, items) assert q.size() == 10 assert q.bound() == 1 removed = q.filter(lambda data: \ Node._extract_bound(data) >= 5) assert q.size() == 6 assert len(removed) == 4 for data in removed: assert Node._extract_bound(data) < 5 assert q.bound() == 5 for i in range(5, 11): node = Node(data_=q.get()) assert node.bound == i assert node.queue_priority == -i if i != 10: assert q.bound() == i + 1 else: assert q.bound() is None assert q.size() == 0 node = Node(size=0) node.bound = 0 node.queue_priority = 1 cnt_, data = q.put_get(node._data) assert cnt_ == 10 assert data is node._data assert node.queue_priority == 1 assert q.bound() is None node.queue_priority = 2 cnt_ = q.put(node._data) assert node.queue_priority == 2 assert cnt_ == 11 assert q.bound() == 0 node2 = Node(size=0) node2.bound = 1 node2.queue_priority = 3 cnt_, data = q.put_get(node2._data) assert cnt_ == 12 assert data is node2._data assert node2.queue_priority == 3 assert q.bound() == 0 node2.queue_priority = 1 cnt_, data = q.put_get(node2._data) assert node2.queue_priority == 1 assert cnt_ == 13 assert data is node._data assert q.size() == 1 assert q.bound() == 1
def test_initialize_queue(self): node_limit = None time_limit = None queue_limit = None track_bound = True log = get_simple_logger() log_interval_seconds = inf log_new_incumbent = True convergence_checker = ConvergenceChecker(minimize) root = Node() root.tree_depth = 0 root.bound = convergence_checker.unbounded_objective root.objective = convergence_checker.infeasible_objective queue = DispatcherQueueData([root], None, minimize) best_node_ = Node() best_node_.objective = 0 best_node_._generate_uuid() disp = DispatcherLocal() disp.initialize( convergence_checker.infeasible_objective, best_node_, queue, "bound", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert disp.best_objective == 0 assert disp.best_node.objective == 0 assert disp.best_node is best_node_ disp.initialize( -1, best_node_, queue, "bound", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert disp.best_objective == -1 assert disp.best_node.objective == 0 assert disp.best_node is best_node_ best_node_.objective = 1 disp.initialize( 2, best_node_, queue, "bound", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert disp.best_objective == 1 assert disp.best_node.objective == 1 assert disp.best_node is best_node_ best_node_.objective = 1 root.objective = -1 disp.initialize( 2, best_node_, queue, "bound", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert disp.best_objective == 1 assert disp.best_node.objective == 1 assert disp.best_node is best_node_ best_node_.objective = 1 root.objective = -1 disp.initialize( -2, best_node_, queue, "bound", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert disp.best_objective == -2 assert disp.best_node.objective == 1 assert disp.best_node is best_node_ # bad objective sense queue = DispatcherQueueData([root], None, maximize) with pytest.raises(ValueError): disp.initialize( convergence_checker.infeasible_objective, best_node_, queue, "bound", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, )
def test_overwrites_queue_priority(self): q = LocalGapPriorityQueue(sense=minimize, track_bound=True) node = Node() node.tree_depth = 0 node.bound = -inf node.objective = inf assert node.queue_priority is None assert q.put(node) == 0 assert node.queue_priority is not None assert node.queue_priority == inf child = _new_child(node) assert child.bound == -inf assert child.objective == inf child.bound = 0 assert child.queue_priority is None assert q.put(child) == 1 assert child.queue_priority is not None assert child.queue_priority == inf child = _new_child(child) assert child.bound == 0 assert child.objective == inf child.objective = 1 assert child.queue_priority is None assert q.put(child) == 2 assert child.queue_priority is not None assert child.queue_priority == 1 l1 = Node() l1.tree_depth = 0 l1.bound = 1 l1.objective = 5 l2 = _new_child(l1) l3 = _new_child(l2) q = LocalGapPriorityQueue(sense=minimize, track_bound=True) assert l2.queue_priority is None cnt = q.put(l2) node_ = q.get() assert node_ is l2 assert l2.queue_priority is not None assert l2.queue_priority == 4 assert cnt == 0 cnt = q.put(l2) assert cnt == 1 assert l3.queue_priority is None l3.objective = 6 cnt = q.put(l3) node_ = q.get() assert cnt == 2 assert l3.queue_priority is not None assert l3.queue_priority == 5 assert node_ is l3 q = LocalGapPriorityQueue(sense=maximize, track_bound=True) node = Node() node.tree_depth = 0 node.bound = inf node.objective = -inf assert node.queue_priority is None assert q.put(node) == 0 assert node.queue_priority is not None assert node.queue_priority == inf child = _new_child(node) assert child.bound == inf assert child.objective == -inf child.bound = 0 assert child.queue_priority is None assert q.put(child) == 1 assert child.queue_priority is not None assert child.queue_priority == inf child = _new_child(child) assert child.bound == 0 assert child.objective == -inf child.objective = -1 assert child.queue_priority is None assert q.put(child) == 2 assert child.queue_priority is not None assert child.queue_priority == 1 l1 = Node() l1.tree_depth = 0 l1.bound = -1 l1.objective = -5 l2 = _new_child(l1) l3 = _new_child(l2) q = LocalGapPriorityQueue(sense=maximize, track_bound=True) assert l2.queue_priority is None cnt = q.put(l2) node_ = q.get() assert node_ is l2 assert l2.queue_priority is not None assert l2.queue_priority == 4 assert cnt == 0 cnt = q.put(l2) assert cnt == 1 assert l3.queue_priority is None l3.objective = -6 cnt = q.put(l3) node_ = q.get() assert cnt == 2 assert l3.queue_priority is not None assert l3.queue_priority == 5 assert node_ is l3
def test_queue_strategy(self): node_limit = None time_limit = None queue_limit = None track_bound = True log = get_simple_logger() log_interval_seconds = inf log_new_incumbent = True convergence_checker = ConvergenceChecker(minimize) root = Node() root.tree_depth = 0 root.bound = convergence_checker.unbounded_objective root.objective = convergence_checker.infeasible_objective queue = DispatcherQueueData([root], None, minimize) disp = DispatcherLocal() disp.initialize( convergence_checker.infeasible_objective, None, queue, "bound", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is WorstBoundFirstPriorityQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "custom", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is CustomPriorityQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "objective", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is BestObjectiveFirstPriorityQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "breadth", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is BreadthFirstPriorityQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "depth", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is DepthFirstPriorityQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "fifo", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is FIFOQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "lifo", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is LIFOQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "random", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is RandomPriorityQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, "local_gap", convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is LocalGapPriorityQueue disp.initialize( convergence_checker.infeasible_objective, None, queue, ("bound", "local_gap"), convergence_checker, node_limit, time_limit, queue_limit, track_bound, log, log_interval_seconds, log_new_incumbent, ) assert type(disp.queue) is LexicographicPriorityQueue
def test_usage_maximize(self): q = CustomPriorityQueue(sense=maximize, track_bound=True) assert q.size() == 0 assert q.bound() is None assert len(list(q.items())) == 0 assert q.get() is None items = [] for i in range(1, 11): node = Node() node.bound = -i node.queue_priority = i assert q.put(node) == i - 1 assert node.queue_priority == i items.append(node) assert q.size() == i assert q.bound() == -1 _check_items(q, items) assert q.size() == 10 assert q.bound() == -1 removed = q.filter(lambda n_: n_.bound <= -5) assert q.size() == 6 assert len(removed) == 4 for node_ in removed: assert node_.bound > -5 assert q.bound() == -5 for i in range(10, 4, -1): node = q.get() assert node.bound == -i assert node.queue_priority == i if i != 5: assert q.bound() == -5 else: assert q.bound() is None assert q.size() == 0 node = Node() node.bound = 0 node.queue_priority = 1 cnt_ = q.put(node) node_ = q.get() assert cnt_ == 10 assert node_ is node assert node.queue_priority == 1 assert q.bound() is None node.queue_priority = 2 cnt_ = q.put(node) assert node.queue_priority == 2 assert cnt_ == 11 assert q.bound() == 0 node2 = Node() node2.bound = 1 node2.queue_priority = 3 cnt_ = q.put(node2) node_ = q.get() assert cnt_ == 12 assert node_ is node2 assert node2.queue_priority == 3 assert q.bound() == 0 node2.queue_priority = 1 cnt_ = q.put(node2) node_ = q.get() assert node2.queue_priority == 1 assert cnt_ == 13 assert node_ is node assert q.size() == 1 assert q.bound() == 1 # no bound tracking q = CustomPriorityQueue(sense=maximize, track_bound=False) assert q.size() == 0 assert q.bound() is None assert len(list(q.items())) == 0 assert q.get() is None items = [] for i in range(1, 11): node = Node() node.bound = -i node.queue_priority = i assert q.put(node) == i - 1 assert node.queue_priority == i items.append(node) assert q.size() == i assert q.bound() == inf _check_items(q, items) assert q.size() == 10 assert q.bound() == inf removed = q.filter(lambda n_: n_.bound <= -5) assert q.size() == 6 assert len(removed) == 4 for node_ in removed: assert node_.bound > -5 assert q.bound() == inf for i in range(10, 4, -1): node = q.get() assert node.bound == -i assert node.queue_priority == i if i != 5: assert q.bound() == inf else: assert q.bound() is None assert q.size() == 0