Beispiel #1
0
    def test_branch(self):
        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)
        rtn = node.bound({})

        # check function calls
        with patch.object(node, '_check_pseudo_costs') as cpc, \
                patch.object(node, '_best_pseudo_costs_index') as bpci, \
                patch.object(node, '_base_branch') as bb:
            cpc.return_value = []
            bpci.return_value = 2
            node.branch(rtn['_pseudo_costs'])
            self.assertTrue(cpc.called)
            self.assertTrue(bpci.called)
            self.assertTrue(bb.called)

        # check return
        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)
        rtn = node.bound({})
        rtn = node.branch(rtn['_pseudo_costs'])
        for direction in ['up', 'down']:
            self.assertTrue(direction in rtn,
                            f'{direction} must be in the returned dict')
            self.assertTrue(isinstance(rtn[direction], PseudoCostBranchNode))
Beispiel #2
0
    def test_calculate_costs(self):
        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)
        node.pseudo_costs = {}
        node._base_bound()

        # check that each fractional index gets proper pseudo cost instantiated
        # check that infeasible strong branch direction gets (0, 1) ie up and x >= 2
        for idx in [1, 2]:
            for strong_branch_node in node._strong_branch(idx).values():
                node._calculate_costs(strong_branch_node)
        for idx, direction in product([1, 2], ['up', 'down']):
            self.assertTrue(node.pseudo_costs[idx][direction]['times'] == 1)
            if idx == 1 and direction == 'down':
                self.assertTrue(node.pseudo_costs[idx][direction]['cost'] == 1)
            else:
                self.assertTrue(node.pseudo_costs[idx][direction]['cost'] == 0)

        # check that branched on index updates the instantiated value correctly
        rtn = node._base_branch(1)
        for direction, child_node in rtn.items():
            child_node.pseudo_costs = node.pseudo_costs
            child_node._base_bound()
            child_node._calculate_costs(child_node)
        for direction in ['up', 'down']:
            self.assertTrue(node.pseudo_costs[1][direction]['times'] == 2)
            if direction == 'down':
                self.assertTrue(node.pseudo_costs[1][direction]['cost'] == 1)
            else:
                self.assertTrue(node.pseudo_costs[1][direction]['cost'] == 0)
Beispiel #3
0
    def test_check_pseudo_costs(self):
        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)

        # check good
        self.assertFalse(node._check_pseudo_costs({}), 'empty should be fine')
        pc = {
            1: {
                'up': {
                    'cost': 0,
                    'times': 0
                },
                'down': {
                    'cost': 0,
                    'times': 0
                }
            }
        }
        self.assertFalse(node._check_pseudo_costs(pc),
                         'good dict should be fine')

        # check bad times
        pc[1]['down']['times'] = -1
        err = node._check_pseudo_costs(pc)[0]
        self.assertTrue(
            err == 'index 1 direction down times must be nonnegative int',
            "check pc[1]['down']['times']")
        del pc[1]['down']['times']
        err = node._check_pseudo_costs(pc)[0]
        self.assertTrue(err == 'index 1 direction down missing times',
                        "check pc[1]['down']")

        # check bad costs
        pc[1]['down']['cost'] = -1
        err = node._check_pseudo_costs(pc)[0]
        self.assertTrue(
            err == 'index 1 direction down cost must be nonnegative number',
            "check pc[1]['down']['cost']")
        del pc[1]['down']['cost']
        err = node._check_pseudo_costs(pc)[0]
        self.assertTrue(err == 'index 1 direction down missing cost',
                        "check pc[1]['down']")

        # check missing direction
        del pc[1]['down']
        err = node._check_pseudo_costs(pc)[0]
        self.assertTrue(err == 'index 1 missing direction down', "check pc[1]")

        # check bad integers
        pc[15] = 'hi'
        del pc[1]
        err = node._check_pseudo_costs(pc)[0]
        self.assertTrue(err == 'index 15 not integer index',
                        "pc[15] should error")
Beispiel #4
0
 def test_branch_fails_assertions(self):
     pc = {1: 'hi'}
     node = PseudoCostBranchNode(small_branch.lp,
                                 small_branch.integerIndices)
     self.assertRaisesRegex(AssertionError,
                            'pseudo cost dict has following errors:',
                            node.branch, pc)
     node.mip_feasible = True
     self.assertRaisesRegex(AssertionError,
                            'must have fractional value to branch',
                            node.branch, pc)
Beispiel #5
0
 def test_bound_fails_assertions(self):
     pc = {1: 'hi'}
     node = PseudoCostBranchNode(small_branch.lp,
                                 small_branch.integerIndices)
     self.assertRaisesRegex(AssertionError,
                            'pseudo cost dict has following errors:',
                            node.bound, pc)
Beispiel #6
0
 def test_best_pseudo_cost_index(self):
     pc = {
         1: {
             'up': {
                 'cost': 1,
                 'times': 1
             },
             'down': {
                 'cost': 1,
                 'times': 1
             }
         },
         2: {
             'up': {
                 'cost': 1,
                 'times': 1
             },
             'down': {
                 'cost': 1,
                 'times': 1
             }
         }
     }
     node = PseudoCostBranchNode(small_branch.lp,
                                 small_branch.integerIndices)
     node.solution = [0, 1.25, 2.5]
     self.assertTrue(node._best_pseudo_costs_index(pc) == 2)
     pc[1] = {
         'up': {
             'cost': 10,
             'times': 1
         },
         'down': {
             'cost': 1,
             'times': 1
         }
     }
     self.assertTrue(node._best_pseudo_costs_index(pc) == 2)
     pc[1] = {
         'up': {
             'cost': 10,
             'times': 1
         },
         'down': {
             'cost': 10,
             'times': 1
         }
     }
     self.assertTrue(node._best_pseudo_costs_index(pc) == 1)
Beispiel #7
0
    def test_update_pseudo_costs(self):
        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)
        node.pseudo_costs = {}
        node._base_bound()

        # for root node (sb_index = 2)
        # check we call strong branch once and calculate costs twice for each sb_index
        with patch.object(node, '_strong_branch') as sb, \
                patch.object(node, '_calculate_costs') as cc:
            sb.return_value = {
                'up':
                PseudoCostBranchNode(small_branch.lp,
                                     small_branch.integerIndices),
                'down':
                PseudoCostBranchNode(small_branch.lp,
                                     small_branch.integerIndices)
            }
            node._update_pseudo_costs()
            self.assertTrue(sb.call_count == 2)
            self.assertTrue(cc.call_count == 4)

        # branch on 2 (len(sb_index) = 1)
        # check we call strong branch len(sb_index) times and calc costs 2*len(sb_index) + 1
        rtn = node._base_branch(2)  # force x0 to go from int to fractional
        down_node = rtn['down']  # just do down bc up infeasible
        down_node.pseudo_costs = {
            1: {
                'up': {
                    'cost': 0,
                    'times': 1
                },
                'down': {
                    'cost': 1,
                    'times': 1
                }
            },
            2: {
                'up': {
                    'cost': 0,
                    'times': 1
                },
                'down': {
                    'cost': 0,
                    'times': 1
                }
            }
        }
        down_node._base_bound()
        with patch.object(down_node, '_strong_branch') as sb, \
                patch.object(down_node, '_calculate_costs') as cc:
            sb.return_value = {
                'up':
                PseudoCostBranchNode(small_branch.lp,
                                     small_branch.integerIndices),
                'down':
                PseudoCostBranchNode(small_branch.lp,
                                     small_branch.integerIndices)
            }
            down_node._update_pseudo_costs()
            self.assertTrue(sb.call_count == 1)
            self.assertTrue(cc.call_count == 3)
Beispiel #8
0
    def test_bound(self):
        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)
        rtn = node.bound({})

        # check assignments
        for idx, direction in product([1, 2], ['up', 'down']):
            self.assertTrue(node.pseudo_costs[idx][direction]['times'] == 1)
            if idx == 1 and direction == 'down':
                self.assertTrue(node.pseudo_costs[idx][direction]['cost'] == 1)
            else:
                self.assertTrue(node.pseudo_costs[idx][direction]['cost'] == 0)
        self.assertTrue(node.strong_branch_iters == 5)

        # check returns
        for idx, direction in product([1, 2], ['up', 'down']):
            self.assertTrue(rtn['_pseudo_costs'][idx][direction]['times'] == 1)
            if idx == 1 and direction == 'down':
                self.assertTrue(
                    rtn['_pseudo_costs'][idx][direction]['cost'] == 1)
            else:
                self.assertTrue(
                    rtn['_pseudo_costs'][idx][direction]['cost'] == 0)

        # check function calls
        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)
        node.lp_feasible = False
        with patch.object(node, '_check_pseudo_costs') as cpc, \
                patch.object(node, '_base_bound') as bb, \
                patch.object(node, '_update_pseudo_costs') as upc:
            cpc.return_value = []
            node.bound({})
            self.assertTrue(cpc.call_count == 1)
            self.assertTrue(bb.call_count == 1)
            self.assertTrue(upc.call_count == 0)

        node = PseudoCostBranchNode(small_branch.lp,
                                    small_branch.integerIndices)
        node.lp_feasible = True
        with patch.object(node, '_check_pseudo_costs') as cpc, \
                patch.object(node, '_base_bound') as bb, \
                patch.object(node, '_update_pseudo_costs') as upc:
            cpc.return_value = []
            node.bound({})
            self.assertTrue(cpc.call_count == 1)
            self.assertTrue(bb.call_count == 1)
            self.assertTrue(upc.call_count == 1)
Beispiel #9
0
 def test_init(self):
     node = PseudoCostBranchNode(small_branch.lp,
                                 small_branch.integerIndices)
     self.assertTrue(node.branch_method == 'pseudo cost')
     self.assertFalse(node.pseudo_costs, 'should exist but be none')
     self.assertFalse(node.strong_branch_iters, 'should exist but be none')