Example #1
0
    def apply_primal_simplex(self, basis_map):
        ''' Applies primal simplex to the matrix
            using a feasible basis. '''

        M = self.Mx
        h, w = M.shape

        try:
            # Check input basis
            self.check_basis_map(basis_map)

            # Apply pivoting loop using primal pivot picker
            self.pivoting_loop(self.pick_primal_pivot, basis_map)

            # Setup optimal result
            self.setup_optimal_result(basis_map)

            status = Status.OPTIMAL
        except UnboundedException as e:
            # LP is unbounded.
            # Build unboundedness certificate.
            idx = self.neg_col

            self.cert = np.matrix([ff(0)] * (w - h))
            self.cert[0, idx - h + 1] = ff(1)

            for row in basis_map:
                self.cert[0, basis_map[row] - h + 1] = -M[row, idx]

            self.cert = self.cert[0, :-h + 1]
            status = Status.UNBOUNDED

        return status
Example #2
0
    def add_restriction(self, restriction_row, basis_map, slack=0):
        '''
            Adds a new restriction to an already found solution.
            slack may be set to 0 (=), 1 (<=) or -1 (>=).
        '''

        if self.opt_val is None:
            return
        h, w = self.Mx.shape

        # Add the restriction and slack variables.
        slack_col = np.matrix(np.zeros(shape=(h + 1, 1), dtype='object'))
        slack_col[-1, 0] = ff(slack)

        self.Mx = np.concatenate([self.Mx, restriction_row])
        self.Mx = np.concatenate([
            self.Mx[:, :h - 1], slack_col, self.Mx[:, h - 1:-1], slack_col,
            self.Mx[:, -1]
        ],
                                 axis=1)

        if self.debug:
            print('[Add restriction (' + str(slack) + ')]',
                  StdLP.printable(restriction_row))
            print(self)

        basis_map[h] = w - 1
        for row in basis_map:
            basis_map[row] += 1
Example #3
0
    def append_log(A):
        ''' Appends the logging matrix to the tableau. '''

        h, w = A.shape
        log = np.concatenate(
            (np.matrix([ff(0)] * (h - 1)), StdLP.fidentity(h - 1)), axis=0)

        return np.concatenate((log, A), axis=1)
Example #4
0
    def apply_cutting_plane(self, basis_map):
        ''' Applies the cutting plane method to solve
            the integer programming problem. '''

        # Apply simplex to linear relaxation.
        status = self.apply_simplex(basis_map)

        # Cancel method if not optimal
        if status != Status.OPTIMAL:
            return status

        # Save results for linear relaxation.
        self.lr_cert = self.cert.copy()
        self.lr_opt_vec = self.opt_vec.copy()
        self.lr_opt_val = self.opt_val

        last = status
        integer = False
        c = 1
        while not integer:
            # Get dimensions.
            h, w = self.Mx.shape

            # Assume this is the last iteration of the loop.
            integer = True
            for y in range(1, h):
                # Skip integer entries and slack variables
                if self.Mx[y, -1].denominator == 1 or basis_map[y] >= w - h:
                    continue

                # Break loop assumption.
                integer = False

                # Pick fractional entry.
                row = y

                print('[Cutting plane', c, 'for row ' + str(row) + ']')

                # Build restriction.
                restriction = self.Mx[row, :].copy()
                for x in range(w):
                    if x >= h - 1:
                        restriction[0, x] = ff(floor(restriction[0, x]))
                    else:
                        restriction[0, x] = 0

                # Enforce restriction on existing solution.
                self.add_restriction(restriction, basis_map, slack=1)
                last = self.restore_solution_after_restriction(basis_map)
                print('[Optimal]', self.Mx[0, -1])

                if self.debug:
                    print(self)

                c += 1

        return last
Example #5
0
    def build_aux(M):
        ''' Builds the auxiliary tableau. '''

        h, w = M.shape

        # Clear target function.
        M[0] -= M[0]

        # Appended matrix
        aux = np.concatenate(
            (np.matrix([ff(1)] * (h - 1)), StdLP.fidentity(h - 1)), axis=0)

        new_M = np.concatenate((M[:, :-1], aux, M[:, -1]), axis=1)
        return new_M
Example #6
0
    def setup_optimal_result(self, basis_map):
        ''' Sets up the optimal result given a final tableau
            and the basis. '''

        h, w = self.Mx.shape

        # Optimal value.
        self.opt_val = self.Mx[0, -1]

        # Optimal vector.
        self.opt_vec = np.matrix([ff(0)] * w)
        for row in basis_map:
            self.opt_vec[0, basis_map[row]] = self.Mx[row, -1]

        # Delete log and slack entries from optimal vector.
        self.opt_vec = self.opt_vec[0, h - 1:-h]

        # Certificate of optimality.
        self.cert = self.Mx[0, :h - 1]
Example #7
0
 def fidentity(n):
     ''' Identity matrix of Fraction objects. '''
     return np.identity(n, dtype='object') + ff()
Example #8
0
    def _apply_bb_rec(self, Mo, basis_map, lvl=0):
        ''' Heavy work for recursive branch and bound. '''

        M = Mo.copy()
        h, w = M.shape

        for row in range(1, h):
            # Skip integer entries.
            if M[row, -1].denominator == 1:
                continue

            # Skip slack variables.
            col = basis_map[row]
            if col >= w - h:
                continue

            # Build 1st restriction
            r1 = M[row, :].copy()
            for x in range(w):
                r1[0, x] = ff(0)
            r1[0, col] = ff(1)
            r1[0, -1] = ff(floor(M[row, -1]))

            print((' ' * lvl) + '[Branch] x_' + str(col - h + 1) + ' <= ' +
                  str(r1[0, -1]))

            # Copy basis and input matrix
            basis = dict()
            basis.update(basis_map)
            self.Mx = M.copy()

            # Add 1st restriction
            self.add_restriction(r1, basis, slack=1)
            # Restore basis (optimized, just need to pivot branch var)
            self.pivot(row, basis[row])
            # Restore solution if needed
            status = self.apply_dual_simplex(basis)
            if self.debug:
                print(self)

            # Left branch
            if status == Status.OPTIMAL:
                if not self.bb_best_val or self.opt_val > self.bb_best_val:
                    if StdLP.all_integer(self.opt_vec):
                        # Update solution
                        self.bb_best_val = self.opt_val
                        self.bb_best_vec = self.opt_vec
                    else:
                        # Explore branch
                        self._apply_bb_rec(self.Mx, basis, lvl=lvl + 1)
                    print((' ' * lvl) + '[Optimal]', self.bb_best_val)
                else:
                    # Prune branch
                    print((' ' * lvl) + '[Pruned]')

            # Build 2nd restriction
            r2 = M[row, :].copy()
            for x in range(w):
                r2[0, x] = ff(0)
            r2[0, col] = ff(1)
            r2[0, -1] = ff(ceil(M[row, -1]))

            print((' ' * lvl) + '[Branch] x_' + str(col - h + 1) + ' >= ' +
                  str(r2[0, -1]))

            # Copy basis and input matrix
            basis = dict()
            basis.update(basis_map)
            self.Mx = M.copy()

            # Add 2nd restriction
            self.add_restriction(r2, basis, slack=-1)
            # Restore basis (optimized, just need to pivot branch var and slack)
            self.pivot(row, basis[row])
            self.pivot(h, w)
            # Restore solution if needed
            status = self.apply_dual_simplex(basis)
            if self.debug:
                print(self)
                print('[' + str(status) + ']')

            # Right branch
            if status == Status.OPTIMAL:
                if not self.bb_best_val or self.opt_val > self.bb_best_val:
                    if StdLP.all_integer(self.opt_vec):
                        # Update solution
                        self.bb_best_val = self.opt_val
                        self.bb_best_vec = self.opt_vec
                    else:
                        # Explore branch
                        self._apply_bb_rec(self.Mx, basis, lvl=lvl + 1)
                        print((' ' * lvl) + '[Optimal]', self.opt_val)
                else:
                    # Prune branch
                    print((' ' * lvl) + '[Pruned]', self.opt_val, '<=',
                          self.bb_best_val)
Example #9
0
    if len(sys.argv) < 2:
        fin = sys.stdin
    else:
        infile = sys.argv[1]
        fin = open(infile)

    # Input.
    m = int(fin.readline())
    n = int(fin.readline())
    matrix_line = fin.readline().strip()

    # Build input matrix & canonical basis.
    matrix = np.matrix(matrix_line, dtype='object').reshape(m + 1, n + 1)
    for i in range(0, m + 1):
        for j in range(0, n + 1):
            matrix[i, j] = ff(matrix[i, j])

    A = matrix[1:]
    c = matrix[0]
    std_A, std_c = StdLP.leq_to_std(A, c)
    std_matrix = np.concatenate((-std_c, std_A), axis=0)

    # Initial basis from slack variables
    basis_map = {}
    for i in range(1, m + 1):
        basis_map[i] = m + n + i - 1

    # Instantiate LP problem.
    problem = StdLP(std_matrix,
                    logfile='pivoting.txt',
                    debug=False,
    Kurtosis = E[(X - mu)^4] / ( E[(X-mu)^2] )^2
    '''

    this_numerator = central_moment(pms, 4)
    this_denominator = (population_variance(pms)) ** 2

    return this_numerator / this_denominator

def coefficient_of_variation(pms):
    '''
    Compute standard deviation / mean
    '''
    return sqrt(population_variance(pms)) / raw_moment(pms, 1)

six_pdf = [
    [2, ff(2048,2 ** 17)],
    [3, ff(12288,2 ** 17)],
    [4, ff(16512,2 ** 17)],
    [5, ff(18432,2 ** 17)],
    [6, ff(20976,2 ** 17)],
    [7, ff(16464,2 ** 17)],
    [8, ff(14796,2 ** 17)],
    [9, ff(11220,2 ** 17)],
    [10, ff(7168,2 ** 17)],
    [11, ff(5172,2 ** 17)],
    [12, ff(3031,2 ** 17)],
    [13, ff(1495,2 ** 17)],
    [14, ff(831,2 ** 17)],
    [15, ff(407,2 ** 17)],
    [16, ff(161,2 ** 17)],
    [17, ff(57,2 ** 17)],