コード例 #1
0
    def solve_with_dual_simplex_method(self):
        self._prepare_task_for_dual_simplex_method()

        while True:
            A_basis = np.array([self.matrix_a[:, j]
                                for j in self.j_basis]).transpose()
            B = reversal_matrix(A_basis)
            kappa = np.dot(B, self.vector_b)

            negative_kappas = filter(lambda k: k[1] < 0, enumerate(kappa))

            if not negative_kappas:
                x = [0] * self.n
                for num, j in enumerate(self.j_basis):
                    x[j] = kappa[num]
                self._result_x = x
                self._result_y = self.y
                return True

            delta = min([(nd[1], nd[0]) for nd in negative_kappas])
            js = delta[1]

            mu = [np.dot(B[js], self.matrix_a[:, j]) for j in self.j_not_basis]
            sigma = min([[
                (self.vector_c[j] -
                 np.dot(self.matrix_a[:, j].transpose(), self.y)) / mu[num], j
            ] for num, j in enumerate(self.j_not_basis) if mu[num] < 0]
                        or [None])
            if sigma is None:
                self._exception_message = "Set of permissible plans is empty"
                return False

            self.y = self.y + sigma[0] * B[js]
            j0 = sigma[1]

            js = self.j_basis[js]

            for i in xrange(len(self.j_not_basis)):
                if self.j_not_basis[i] == j0:
                    self.j_not_basis[i] = js
                    break

            for i in xrange(len(self.j_basis)):
                if self.j_basis[i] == js:
                    self.j_basis[i] = j0
                    break
コード例 #2
0
ファイル: linear_programming.py プロジェクト: kavaliou/MOiU
    def solve_with_dual_simplex_method(self):
        self._prepare_task_for_dual_simplex_method()

        while True:
            A_basis = np.array([self.matrix_a[:, j] for j in self.j_basis]).transpose()
            B = reversal_matrix(A_basis)
            kappa = np.dot(B, self.vector_b)

            negative_kappas = filter(lambda k: k[1] < 0, enumerate(kappa))

            if not negative_kappas:
                x = [0] * self.n
                for num, j in enumerate(self.j_basis):
                    x[j] = kappa[num]
                self._result_x = x
                self._result_y = self.y
                return True

            delta = min([(nd[1], nd[0]) for nd in negative_kappas])
            js = delta[1]

            mu = [np.dot(B[js], self.matrix_a[:, j]) for j in self.j_not_basis]
            sigma = min(
                [[(self.vector_c[j] - np.dot(self.matrix_a[:, j].transpose(), self.y)) / mu[num], j] for num, j in
                 enumerate(self.j_not_basis) if mu[num] < 0]
                or [None])
            if sigma is None:
                self._exception_message = "Set of permissible plans is empty"
                return False

            self.y = self.y + sigma[0] * B[js]
            j0 = sigma[1]

            js = self.j_basis[js]

            for i in xrange(len(self.j_not_basis)):
                if self.j_not_basis[i] == j0:
                    self.j_not_basis[i] = js
                    break

            for i in xrange(len(self.j_basis)):
                if self.j_basis[i] == js:
                    self.j_basis[i] = j0
                    break
コード例 #3
0
ファイル: linear_programming.py プロジェクト: kavaliou/MOiU
    def _prepare_task_for_simplex_method(self):
        self._set_variables()

        self.n = len(self.vector_c)

        assert self.x0 is not None or self.j_basis is not None

        if self.j_basis is None:
            self.j_basis = [num for num, i in enumerate(self.x0) if i]

        self.j_not_basis = [j for j in xrange(self.n) if j not in self.j_basis]

        self.matrix_a_basis = np.array([self.matrix_a[:, j] for j in self.j_basis]).transpose()

        self.matrix_b = reversal_matrix(self.matrix_a_basis)

        if self.x0 is None:
            self.x0 = [0] * self.n
            for num, i in enumerate(np.dot(self.matrix_b, self.vector_b)):
                self.x0[self.j_basis[num]] = i
コード例 #4
0
    def _prepare_task_for_dual_simplex_method(self):
        self._set_variables()
        self.n = len(self.vector_c)
        self.m = len(self.vector_b)

        answer = []

        def gen(n, m, mas=None):
            if mas is None:
                mas = []

            for i in range(n):
                if i not in mas:
                    mas.append(i)
                    if m == len(mas):
                        answer.append(mas[:])
                    else:
                        gen(n, m, mas)
                    mas.remove(i)

        if self.j_basis is None:
            gen(self.n, self.m)
            for i in answer:
                matrix_a_basis = np.array([self.matrix_a[:, j]
                                           for j in i]).transpose()
                if np.linalg.det(matrix_a_basis):
                    self.j_basis = i
                    self.matrix_a_basis = matrix_a_basis
                    break

        self.j_not_basis = [j for j in xrange(self.n) if j not in self.j_basis]

        if self.matrix_a_basis is None:
            self.matrix_a_basis = np.array(
                [self.matrix_a[:, j] for j in self.j_basis]).transpose()
        self.matrix_b = reversal_matrix(self.matrix_a_basis)
        c_basis = [
            self.vector_c[j] for j in xrange(self.n) if j in self.j_basis
        ]
        if self.y is None:
            self.y = np.dot(c_basis, self.matrix_b)
コード例 #5
0
    def _prepare_task_for_simplex_method(self):
        self._set_variables()

        self.n = len(self.vector_c)

        assert self.x0 is not None or self.j_basis is not None

        if self.j_basis is None:
            self.j_basis = [num for num, i in enumerate(self.x0) if i]

        self.j_not_basis = [j for j in xrange(self.n) if j not in self.j_basis]

        self.matrix_a_basis = np.array(
            [self.matrix_a[:, j] for j in self.j_basis]).transpose()

        self.matrix_b = reversal_matrix(self.matrix_a_basis)

        if self.x0 is None:
            self.x0 = [0] * self.n
            for num, i in enumerate(np.dot(self.matrix_b, self.vector_b)):
                self.x0[self.j_basis[num]] = i
コード例 #6
0
ファイル: third.py プロジェクト: kavaliou/MOiU
def dual_simplex_method(A, b, C, y, J_b):
    n = len(C)
    J_nb = [j for j in xrange(n) if j not in J_b]

    while True:
        A_basis = np.array([A[:, j] for j in J_b]).transpose()
        B = reversal_matrix(A_basis)
        kappa = np.dot(B, b)

        negative_kappas = filter(lambda k: k[1] < 0, enumerate(kappa))

        if not negative_kappas:
            x = [0] * n
            for num, j in enumerate(J_b):
                x[j] = kappa[num]
            return x, y, J_b

        delta = min([(nd[1], nd[0]) for nd in negative_kappas])
        js = delta[1]

        mu = [np.dot(B[js], A[:, j]) for j in J_nb]
        sigma = min([[(C[j] - np.dot(A[:, j].transpose(), y)) / mu[num], j] for num, j in enumerate(J_nb) if mu[num] < 0]
                    or [None])
        assert sigma is not None, "LOSE Задача не имеет решения, т.к. пусто множество ее допустимых планов."

        y = y + sigma[0] * B[js]
        j0 = sigma[1]

        js = J_b[js]

        for i in xrange(len(J_nb)):
            if J_nb[i] == j0:
                J_nb[i] = js
                break

        for i in xrange(len(J_b)):
            if J_b[i] == js:
                J_b[i] = j0
                break
コード例 #7
0
ファイル: third.py プロジェクト: kavaliou/MOiU
def dual_simplex_method(A, b, C, y, J_b):
    n = len(C)
    J_nb = [j for j in xrange(n) if j not in J_b]

    while True:
        A_basis = np.array([A[:, j] for j in J_b]).transpose()
        B = reversal_matrix(A_basis)
        kappa = np.dot(B, b)

        negative_kappas = filter(lambda k: k[1] < 0, enumerate(kappa))

        if not negative_kappas:
            x = [0] * n
            for num, j in enumerate(J_b):
                x[j] = kappa[num]
            return x, y, J_b

        delta = min([(nd[1], nd[0]) for nd in negative_kappas])
        js = delta[1]

        mu = [np.dot(B[js], A[:, j]) for j in J_nb]
        sigma = min([[(C[j] - np.dot(A[:, j].transpose(), y)) / mu[num], j]
                     for num, j in enumerate(J_nb) if mu[num] < 0] or [None])
        assert sigma is not None, "LOSE Задача не имеет решения, т.к. пусто множество ее допустимых планов."

        y = y + sigma[0] * B[js]
        j0 = sigma[1]

        js = J_b[js]

        for i in xrange(len(J_nb)):
            if J_nb[i] == j0:
                J_nb[i] = js
                break

        for i in xrange(len(J_b)):
            if J_b[i] == js:
                J_b[i] = j0
                break
コード例 #8
0
ファイル: linear_programming.py プロジェクト: kavaliou/MOiU
    def _prepare_task_for_dual_simplex_method(self):
        self._set_variables()
        self.n = len(self.vector_c)
        self.m = len(self.vector_b)

        answer = []

        def gen(n, m, mas=None):
            if mas is None:
                mas = []

            for i in range(n):
                if i not in mas:
                    mas.append(i)
                    if m == len(mas):
                        answer.append(mas[:])
                    else:
                        gen(n, m, mas)
                    mas.remove(i)

        if self.j_basis is None:
            gen(self.n, self.m)
            for i in answer:
                matrix_a_basis = np.array([self.matrix_a[:, j] for j in i]).transpose()
                if np.linalg.det(matrix_a_basis):
                    self.j_basis = i
                    self.matrix_a_basis = matrix_a_basis
                    break

        self.j_not_basis = [j for j in xrange(self.n) if j not in self.j_basis]

        if self.matrix_a_basis is None:
            self.matrix_a_basis = np.array([self.matrix_a[:, j] for j in self.j_basis]).transpose()
        self.matrix_b = reversal_matrix(self.matrix_a_basis)
        c_basis = [self.vector_c[j] for j in xrange(self.n) if j in self.j_basis]
        if self.y is None:
            self.y = np.dot(c_basis, self.matrix_b)
コード例 #9
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_1(self):
     c1 = np.array([1, 2, 2, 4, 1, 2, 4, 2, 3], dtype=np.float).reshape(
         (3, 3))
     answer1 = [[1, 2, -2], [4, 5, -6], [-4, -6, 7]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c1)),
                                          np.array(answer1))
コード例 #10
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_2(self):
     c2 = np.array([0, 2, 1, 0, 1, 1, 1, 1, 1], dtype=np.float).reshape((3, 3))
     answer2 = [[0, -1, 1],
                [1, -1, 0],
                [-1, 2, 0]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c2)), np.array(answer2))
コード例 #11
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_6(self):
     c6 = [[0, 2, 3], [0, 1, 1], [1, -1, 2]]
     answer6 = [[-3, 7, 1], [-1, 3, 0], [1, -2, 0]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c6)),
                                          np.array(answer6))
コード例 #12
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_7(self):
     c7 = [[0, 2, 3], [0, 1, 1], [0, 1, 1]]
     with self.assertRaises(ValueError):
         reversal_matrix(c7)
コード例 #13
0
def fifth(A, B, b, d, x0, J_op, J_star=None, c=None, D=None):
    if D is None:
        D = np.dot(B.transpose(), B)
    if J_star is None:
        J_star = J_op[:]
    if c is None:
        c = np.dot(d, B) * -1
    n, m = A.shape

    pass_step_first = False
    while True:
        if not pass_step_first:
            print '+++++++++++++++'
            # step 1
            c_x0 = np.dot(D, x0) + c
            c_op_x0 = np.array(
                [_c for num, _c in enumerate(c_x0) if num in J_op],
                dtype=np.float64)
            A_op = np.array(
                [_A for num, _A in enumerate(A.transpose()) if num in J_op],
                dtype=np.float64).transpose()
            # A_op = np.array([A[:, j] for j in J_op], dtype=np.float64).transpose()
            u_ = -1 * np.dot(c_op_x0.transpose(), reversal_matrix(A_op))
            deltas = np.dot(u_, A) + c_x0

            # step 2
            min_delta, j0 = min([(d, num) for num, d in enumerate(deltas)
                                 if num not in J_star])
            if min_delta >= 0:
                print 'WIN'
                break

        # step 3
        l = [0] * m
        l[j0] = 1
        D_star = np.array([[D[i, j] for j in J_star] for i in J_star],
                          dtype=np.float64)
        D_star_j0 = np.array([D[i, j0] for i in J_star], dtype=np.float64)
        A_star = np.array([A[:, j] for j in J_star],
                          dtype=np.float64).transpose()
        H = np.array([
            list(D_star[i]) + list(A_star.transpose()[i])
            for i in range(D_star.shape[0])
        ] + [
            list(A_star[i]) + [0] * A_star.shape[0]
            for i in range(A_star.shape[0])
        ],
                     dtype=np.float64)
        bb = np.array(list(D_star_j0) + list(A[:, j0]), dtype=np.float64)
        l_J_star__delta_y = -1 * np.dot(reversal_matrix(H), bb)
        l_J_star = l_J_star__delta_y[:D_star.shape[0]]
        delta_y = l_J_star__delta_y[D_star.shape[0]:]
        for num, j in enumerate(J_star):
            l[j] = l_J_star[num]
        l = np.array(l, dtype=np.float64)

        # step 4
        teta = np.array([0] * m, dtype=np.float64)
        for j in J_star:
            if l[j] >= 0:
                teta[j] = 'inf'
            else:
                teta[j] = -1 * x0[j] / l[j]
        delta__ = np.dot(np.dot(l, D), l)
        teta[j0] = (abs(min_delta) / delta__) if delta__ > 0 else 'inf'

        min_teta, j_star = min([(d, num) for num, d in enumerate(teta)
                                if num in J_star or num == j0])

        # step 5
        print min_teta, l
        x0 = x0 + min_teta * l
        # step 6
        print x0
        if j_star == j0:
            print 'a'
            J_star.append(j0)
            pass_step_first = False
        elif j_star in [j for j in J_star if j not in J_op]:
            print 'b'
            J_star.remove(j_star)
            min_delta += min_teta * delta__
            pass_step_first = True
        else:
            __index = 0
            __k = -1
            for val in J_op:
                if j_star == val:
                    __k = __index
            __index += 1
            assert __k != -1
            new_j = -1
            for j_plus in [j for j in J_star if j not in J_op]:
                e = np.array([1 if i == __k else 0 for i in range(n)],
                             dtype=np.float64)
                if np.dot(np.dot(e, reversal_matrix(A_op)),
                          A[:, j_plus]) > 0.0001:
                    new_j = j_plus

            # has_not_null = None
            # for s, js in enumerate(J_op):
            #     for j_plus in [j for j in J_star if j not in J_op]:
            #         e = np.array([1 if i==s else 0 for i in range(n)], dtype=np.float64)
            #         if np.dot(np.dot(e, reversal_matrix(A_op)), A[:, j_plus]) > 0.0001:
            #             has_not_null = True
            #             break
            #     if has_not_null:
            #         break
            # if has_not_null is not None and has_not_null:  # c

            if new_j != -1:
                print 'c'
                J_op.remove(j_star)
                J_op.append(new_j)
                J_star.remove(j_star)
                min_delta += min_teta * delta__
                pass_step_first = True
            else:  # d
                print 'd'
                J_op.remove(j_star)
                J_op.append(j0)
                J_star.remove(j_star)
                J_star.append(j0)
                pass_step_first = False
        print J_star, J_op
        print '--------'
    return x0
コード例 #14
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_5(self):
     c5 = [[0, 2, 3], [0, 1, 1], [1, -1, 1]]
     answer5 = [[-2, 5, 1], [-1, 3, 0], [1, -2, 0]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c5)),
                                          np.array(answer5))
コード例 #15
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_2(self):
     c2 = np.array([0, 2, 1, 0, 1, 1, 1, 1, 1], dtype=np.float).reshape(
         (3, 3))
     answer2 = [[0, -1, 1], [1, -1, 0], [-1, 2, 0]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c2)),
                                          np.array(answer2))
コード例 #16
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_5(self):
     c5 = [[0, 2, 3], [0, 1, 1], [1, -1, 1]]
     answer5 = [[-2, 5, 1],
                [-1, 3, 0],
                [1, -2, 0]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c5)), np.array(answer5))
コード例 #17
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_7(self):
     c7 = [[0, 2, 3], [0, 1, 1], [0, 1, 1]]
     with self.assertRaises(ValueError):
         reversal_matrix(c7)
コード例 #18
0
ファイル: linear_programming.py プロジェクト: kavaliou/MOiU
    def solve_with_dual_simplex_method_with_constraints(self):
        self._prepare_task_for_dual_simplex_method()
        J = sorted(self.j_basis + self.j_not_basis)
        # step 1
        deltas = [np.dot(self.y, self.matrix_a[:, j]) - self.vector_c[j] for j in J]
        j_not_basis_plus = [num for num, elem in enumerate(deltas)
                            if elem >= 0 and num in self.j_not_basis]
        j_not_basis_minus = [elem for elem in self.j_not_basis
                             if elem not in j_not_basis_plus]

        while True:
            # step 2
            kappas = [0] * self.n
            for j in J:
                if j in j_not_basis_plus:
                    kappas[j] = self.d_bottom[j]
                elif j in j_not_basis_minus:
                    kappas[j] = self.d_top[j]
            s = sum([self.matrix_a[:, j_] * kappas[j_]
                     for j_ in sorted(j_not_basis_minus + j_not_basis_plus)])
            kappas_a = np.dot(self.matrix_b, self.vector_b - s)
            for num, j in enumerate(self.j_basis):
                kappas[j] = kappas_a[num]

            # step 3
            if all(map(lambda (_d_bottom, _kappa, _d_top): _d_bottom <= _kappa <= _d_top,
                       zip(self.d_bottom, kappas, self.d_top))):
                self._result_x = kappas
                return True

            # step 4
            k, j_k = min([(num, j) for num, j in enumerate(self.j_basis)
                          if not (self.d_bottom[j] <= kappas[j] <= self.d_top[j])])

            # step 5
            mu_j_k = 1 if kappas[j_k] < self.d_bottom[j_k] else -1
            delta_y = mu_j_k * np.dot(np.array([1 if i == k else 0 for i in range(len(self.j_basis))]),
                                      self.matrix_b)
            mu = [np.dot(delta_y, self.matrix_a[:, j]) for j in J]

            # step 6
            sigmas = [-float(deltas[j]) / mu[j]
                      if (j in j_not_basis_plus and mu[j] < 0)
                         or (j in j_not_basis_minus and mu[j] > 0) else 'inf'
                      for j in sorted(j_not_basis_plus + j_not_basis_minus)]
            sigmas = zip(sigmas, sorted(j_not_basis_plus + j_not_basis_minus))
            sigma_0, j_star = min(sigmas)
            sigma_0 = float(sigma_0)

            # step 7
            if sigma_0 == float('inf'):
                self._exception_message = "Set of permissible plans is empty"
                return False

            # step 8
            deltas = [deltas[j] + sigma_0 * mu[j] for j in J]
            self.j_basis[k] = j_star
            self.matrix_a_basis = np.array([self.matrix_a[:, j] for j in self.j_basis]).transpose()
            self.matrix_b = reversal_matrix(self.matrix_a_basis)

            # step 9
            self.j_not_basis = [j for j in xrange(self.n) if j not in self.j_basis]
            if j_star in j_not_basis_plus:
                if mu_j_k == 1:
                    j_not_basis_plus[j_not_basis_plus.index(j_star)] = j_k
                else:
                    j_not_basis_plus.remove(j_star)
            else:
                if mu_j_k == 1:
                    j_not_basis_plus.append(j_k)

            j_not_basis_minus = [elem for elem in self.j_not_basis
                                 if elem not in j_not_basis_plus]
コード例 #19
0
ファイル: linear_programming.py プロジェクト: kavaliou/MOiU
    def solve_with_method_gomori(self, log=False):
        self._set_variables()

        def round_function(number, ndigits_for_round=6):
            if round(number, ndigits_for_round) == round(number):
                return int(round(number))
            else:
                return round(number, ndigits_for_round)

        def not_integral_part(number):
            return number - math.floor(number)

        n = len(self.vector_c)
        m = len(self.vector_b)
        j_basis = self.j_basis
        j_all = range(n)
        j_synthetic = []
        m_synthetic = []
        matrix_a = self.matrix_a
        vector_b = self.vector_b
        vector_c = self.vector_c

        while True:
            linear_programming_task = LinearProgrammingTask(
                matrix_a, vector_b, vector_c, j_basis=j_basis[:]
            )
            has_answer = linear_programming_task.solve_with_dual_simplex_method()

            fresh_j_basis = linear_programming_task.j_basis
            x0 = map(round_function, linear_programming_task.result_x)

            print 'x0 =', x0
            print 'j_basis =', fresh_j_basis

            # reduce task size
            synthetic_indexes_for_delete = [j for j in j_synthetic if j in fresh_j_basis]
            while synthetic_indexes_for_delete:
                idx = synthetic_indexes_for_delete[0]
                synthetic_map = dict(zip(j_synthetic, m_synthetic))

                row = matrix_a[synthetic_map[idx], :]
                _b = vector_b[synthetic_map[idx]]
                for i in m_synthetic:
                    if i == synthetic_map[idx]:
                        continue
                    row_for_change = matrix_a[i, :]
                    mul = row_for_change[idx]
                    sub_row = mul * row
                    vector_b[i] = vector_b[i] - mul * _b
                    matrix_a[i, :] = row_for_change - sub_row

                matrix_a = np.delete(matrix_a, idx, 1)
                matrix_a = np.delete(matrix_a, synthetic_map[idx], 0)
                vector_b = np.delete(vector_b, synthetic_map[idx], 0)
                vector_c = np.delete(vector_c, idx, 0)

                j_synthetic.pop()
                m_synthetic.pop()
                n -= 1
                m -= 1
                fresh_j_basis.remove(idx)
                x0.pop((j_all+j_synthetic).index(idx))

                # recalculate
                synthetic_indexes_for_delete = [j for j in j_synthetic if j in fresh_j_basis]

            x_opt = [x for idx, x in enumerate(x0) if idx in fresh_j_basis]
            not_integral_result_x0 = filter(lambda x: not isinstance(x, int), x_opt)

            print 'not integral x0 = ', not_integral_result_x0

            if not not_integral_result_x0:
                self._result_x = x0[:len(j_all)]
                return True

            matrix_a_basis = np.array([matrix_a[:, j] for j in fresh_j_basis]).transpose()
            reverse_a_matrix = reversal_matrix(matrix_a_basis)

            i0 = x0.index(not_integral_result_x0[0])
            s = fresh_j_basis.index(i0)
            y = reverse_a_matrix[s, :]

            print 'i0 =', i0
            print 's =', s

            a = [np.dot(y, matrix_a[:, j]) for j in j_all + j_synthetic]
            b = np.dot(y, vector_b)

            j_array = set(j_all + j_synthetic) - set(fresh_j_basis)

            a_new = [0] * (len(j_all) + len(j_synthetic))
            for j in j_array:
                a_new[j] = -not_integral_part(a[j])
            a_new.append(1)
            print 'new bound in matrix a =', map(round_function, a_new)
            print 'new bound in vector b =', round_function(b)
            m_a = [list(i) + [0] for i in matrix_a]
            m_a.append(a_new)
            matrix_a = np.array(m_a, dtype=np.float64)

            v_b = list(vector_b)
            v_b.append(-not_integral_part(b))
            vector_b = np.array(v_b, dtype=np.float64)

            v_c = list(vector_c)
            v_c.append(0)
            vector_c = np.array(v_c, dtype=np.float64)

            j_synthetic.append(n)
            m_synthetic.append(m)
            j_basis = fresh_j_basis[:]
            j_basis.append(n)
            n += 1
            m += 1

            print '\n----------\n'
コード例 #20
0
    def solve_with_method_gomori(self, log=False):
        self._set_variables()

        def round_function(number, ndigits_for_round=6):
            if round(number, ndigits_for_round) == round(number):
                return int(round(number))
            else:
                return round(number, ndigits_for_round)

        def not_integral_part(number):
            return number - math.floor(number)

        n = len(self.vector_c)
        m = len(self.vector_b)
        j_basis = self.j_basis
        j_all = range(n)
        j_synthetic = []
        m_synthetic = []
        matrix_a = self.matrix_a
        vector_b = self.vector_b
        vector_c = self.vector_c

        while True:
            linear_programming_task = LinearProgrammingTask(matrix_a,
                                                            vector_b,
                                                            vector_c,
                                                            j_basis=j_basis[:])
            has_answer = linear_programming_task.solve_with_dual_simplex_method(
            )

            fresh_j_basis = linear_programming_task.j_basis
            x0 = map(round_function, linear_programming_task.result_x)

            print 'x0 =', x0
            print 'j_basis =', fresh_j_basis

            # reduce task size
            synthetic_indexes_for_delete = [
                j for j in j_synthetic if j in fresh_j_basis
            ]
            while synthetic_indexes_for_delete:
                idx = synthetic_indexes_for_delete[0]
                synthetic_map = dict(zip(j_synthetic, m_synthetic))

                row = matrix_a[synthetic_map[idx], :]
                _b = vector_b[synthetic_map[idx]]
                for i in m_synthetic:
                    if i == synthetic_map[idx]:
                        continue
                    row_for_change = matrix_a[i, :]
                    mul = row_for_change[idx]
                    sub_row = mul * row
                    vector_b[i] = vector_b[i] - mul * _b
                    matrix_a[i, :] = row_for_change - sub_row

                matrix_a = np.delete(matrix_a, idx, 1)
                matrix_a = np.delete(matrix_a, synthetic_map[idx], 0)
                vector_b = np.delete(vector_b, synthetic_map[idx], 0)
                vector_c = np.delete(vector_c, idx, 0)

                j_synthetic.pop()
                m_synthetic.pop()
                n -= 1
                m -= 1
                fresh_j_basis.remove(idx)
                x0.pop((j_all + j_synthetic).index(idx))

                # recalculate
                synthetic_indexes_for_delete = [
                    j for j in j_synthetic if j in fresh_j_basis
                ]

            x_opt = [x for idx, x in enumerate(x0) if idx in fresh_j_basis]
            not_integral_result_x0 = filter(lambda x: not isinstance(x, int),
                                            x_opt)

            print 'not integral x0 = ', not_integral_result_x0

            if not not_integral_result_x0:
                self._result_x = x0[:len(j_all)]
                return True

            matrix_a_basis = np.array([matrix_a[:, j]
                                       for j in fresh_j_basis]).transpose()
            reverse_a_matrix = reversal_matrix(matrix_a_basis)

            i0 = x0.index(not_integral_result_x0[0])
            s = fresh_j_basis.index(i0)
            y = reverse_a_matrix[s, :]

            print 'i0 =', i0
            print 's =', s

            a = [np.dot(y, matrix_a[:, j]) for j in j_all + j_synthetic]
            b = np.dot(y, vector_b)

            j_array = set(j_all + j_synthetic) - set(fresh_j_basis)

            a_new = [0] * (len(j_all) + len(j_synthetic))
            for j in j_array:
                a_new[j] = -not_integral_part(a[j])
            a_new.append(1)
            print 'new bound in matrix a =', map(round_function, a_new)
            print 'new bound in vector b =', round_function(b)
            m_a = [list(i) + [0] for i in matrix_a]
            m_a.append(a_new)
            matrix_a = np.array(m_a, dtype=np.float64)

            v_b = list(vector_b)
            v_b.append(-not_integral_part(b))
            vector_b = np.array(v_b, dtype=np.float64)

            v_c = list(vector_c)
            v_c.append(0)
            vector_c = np.array(v_c, dtype=np.float64)

            j_synthetic.append(n)
            m_synthetic.append(m)
            j_basis = fresh_j_basis[:]
            j_basis.append(n)
            n += 1
            m += 1

            print '\n----------\n'
コード例 #21
0
    def solve_with_dual_simplex_method_with_constraints(self):
        self._prepare_task_for_dual_simplex_method()
        J = sorted(self.j_basis + self.j_not_basis)
        # step 1
        deltas = [
            np.dot(self.y, self.matrix_a[:, j]) - self.vector_c[j] for j in J
        ]
        j_not_basis_plus = [
            num for num, elem in enumerate(deltas)
            if elem >= 0 and num in self.j_not_basis
        ]
        j_not_basis_minus = [
            elem for elem in self.j_not_basis if elem not in j_not_basis_plus
        ]

        while True:
            # step 2
            kappas = [0] * self.n
            for j in J:
                if j in j_not_basis_plus:
                    kappas[j] = self.d_bottom[j]
                elif j in j_not_basis_minus:
                    kappas[j] = self.d_top[j]
            s = sum([
                self.matrix_a[:, j_] * kappas[j_]
                for j_ in sorted(j_not_basis_minus + j_not_basis_plus)
            ])
            kappas_a = np.dot(self.matrix_b, self.vector_b - s)
            for num, j in enumerate(self.j_basis):
                kappas[j] = kappas_a[num]

            # step 3
            if all(
                    map(
                        lambda (_d_bottom, _kappa, _d_top): _d_bottom <= _kappa
                        <= _d_top, zip(self.d_bottom, kappas, self.d_top))):
                self._result_x = kappas
                return True

            # step 4
            k, j_k = min([
                (num, j) for num, j in enumerate(self.j_basis)
                if not (self.d_bottom[j] <= kappas[j] <= self.d_top[j])
            ])

            # step 5
            mu_j_k = 1 if kappas[j_k] < self.d_bottom[j_k] else -1
            delta_y = mu_j_k * np.dot(
                np.array(
                    [1 if i == k else 0
                     for i in range(len(self.j_basis))]), self.matrix_b)
            mu = [np.dot(delta_y, self.matrix_a[:, j]) for j in J]

            # step 6
            sigmas = [
                -float(deltas[j]) / mu[j] if
                (j in j_not_basis_plus and mu[j] < 0) or
                (j in j_not_basis_minus and mu[j] > 0) else 'inf'
                for j in sorted(j_not_basis_plus + j_not_basis_minus)
            ]
            sigmas = zip(sigmas, sorted(j_not_basis_plus + j_not_basis_minus))
            sigma_0, j_star = min(sigmas)
            sigma_0 = float(sigma_0)

            # step 7
            if sigma_0 == float('inf'):
                self._exception_message = "Set of permissible plans is empty"
                return False

            # step 8
            deltas = [deltas[j] + sigma_0 * mu[j] for j in J]
            self.j_basis[k] = j_star
            self.matrix_a_basis = np.array(
                [self.matrix_a[:, j] for j in self.j_basis]).transpose()
            self.matrix_b = reversal_matrix(self.matrix_a_basis)

            # step 9
            self.j_not_basis = [
                j for j in xrange(self.n) if j not in self.j_basis
            ]
            if j_star in j_not_basis_plus:
                if mu_j_k == 1:
                    j_not_basis_plus[j_not_basis_plus.index(j_star)] = j_k
                else:
                    j_not_basis_plus.remove(j_star)
            else:
                if mu_j_k == 1:
                    j_not_basis_plus.append(j_k)

            j_not_basis_minus = [
                elem for elem in self.j_not_basis
                if elem not in j_not_basis_plus
            ]
コード例 #22
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_3(self):
     c3 = [[2, 1, 1], [-1, 0, -1], [1, 1, 2]]
     answer3 = [[0.5, - 0.5, - 0.5],
                [0.5, 1.5, 0.5],
                [-0.5, -0.5, 0.5]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c3)), np.array(answer3))
コード例 #23
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_3(self):
     c3 = [[2, 1, 1], [-1, 0, -1], [1, 1, 2]]
     answer3 = [[0.5, -0.5, -0.5], [0.5, 1.5, 0.5], [-0.5, -0.5, 0.5]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c3)),
                                          np.array(answer3))
コード例 #24
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_4(self):
     c4 = [[0, 1, 1], [-1, 1, -1], [1, 1, 2]]
     answer4 = [[-3, 1, 2],
                [-1, 1, 1],
                [2, -1, -1]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c4)), np.array(answer4))
コード例 #25
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_4(self):
     c4 = [[0, 1, 1], [-1, 1, -1], [1, 1, 2]]
     answer4 = [[-3, 1, 2], [-1, 1, 1], [2, -1, -1]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c4)),
                                          np.array(answer4))
コード例 #26
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_6(self):
     c6 = [[0, 2, 3], [0, 1, 1], [1, -1, 2]]
     answer6 = [[-3, 7, 1],
                [-1, 3, 0],
                [1, -2, 0]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c6)), np.array(answer6))
コード例 #27
0
ファイル: fifth.py プロジェクト: kavaliou/MOiU
def fifth(A, B, b, d, x0, J_op, J_star=None, c=None, D=None):
    if D is None:
        D = np.dot(B.transpose(), B)
    if J_star is None:
        J_star = J_op[:]
    if c is None:
        c = np.dot(d, B) * -1
    n, m = A.shape

    pass_step_first = False
    while True:
        if not pass_step_first:
            print '+++++++++++++++'
            # step 1
            c_x0 = np.dot(D, x0) + c
            c_op_x0 = np.array([_c for num, _c in enumerate(c_x0) if num in J_op], dtype=np.float64)
            A_op = np.array([_A for num, _A in enumerate(A.transpose()) if num in J_op], dtype=np.float64).transpose()
            # A_op = np.array([A[:, j] for j in J_op], dtype=np.float64).transpose()
            u_ = -1 * np.dot(c_op_x0.transpose(), reversal_matrix(A_op))
            deltas = np.dot(u_, A) + c_x0

            # step 2
            min_delta, j0 = min([(d, num) for num, d in enumerate(deltas) if num not in J_star])
            if min_delta >= 0:
                print 'WIN'
                break

        # step 3
        l = [0] * m
        l[j0] = 1
        D_star = np.array([[D[i, j] for j in J_star]for i in J_star], dtype=np.float64)
        D_star_j0 = np.array([D[i, j0] for i in J_star], dtype=np.float64)
        A_star = np.array([A[:, j] for j in J_star], dtype=np.float64).transpose()
        H = np.array(
            [list(D_star[i]) + list(A_star.transpose()[i]) for i in range(D_star.shape[0])] +
            [list(A_star[i]) + [0]*A_star.shape[0] for i in range(A_star.shape[0])], dtype=np.float64)
        bb = np.array(list(D_star_j0) + list(A[:, j0]), dtype=np.float64)
        l_J_star__delta_y = -1 * np.dot(reversal_matrix(H), bb)
        l_J_star = l_J_star__delta_y[:D_star.shape[0]]
        delta_y = l_J_star__delta_y[D_star.shape[0]:]
        for num, j in enumerate(J_star):
            l[j] = l_J_star[num]
        l = np.array(l, dtype=np.float64)

        # step 4
        teta = np.array([0] * m, dtype=np.float64)
        for j in J_star:
            if l[j] >= 0:
                teta[j] = 'inf'
            else:
                teta[j] = -1 * x0[j] / l[j]
        delta__ = np.dot(np.dot(l, D), l)
        teta[j0] = (abs(min_delta) / delta__) if delta__ > 0 else 'inf'

        min_teta, j_star = min([(d, num) for num, d in enumerate(teta) if num in J_star or num == j0])

        # step 5
        print min_teta, l
        x0 = x0 + min_teta * l
        # step 6
        print x0
        if j_star == j0:
            print 'a'
            J_star.append(j0)
            pass_step_first = False
        elif j_star in [j for j in J_star if j not in J_op]:
            print 'b'
            J_star.remove(j_star)
            min_delta += min_teta * delta__
            pass_step_first = True
        else:
            __index = 0
            __k = -1
            for val in J_op:
                if j_star == val:
                    __k = __index
            __index += 1
            assert __k != -1
            new_j = -1
            for j_plus in [j for j in J_star if j not in J_op]:
                e = np.array([1 if i==__k else 0 for i in range(n)], dtype=np.float64)
                if np.dot(np.dot(e, reversal_matrix(A_op)), A[:, j_plus]) > 0.0001:
                    new_j = j_plus

            # has_not_null = None
            # for s, js in enumerate(J_op):
            #     for j_plus in [j for j in J_star if j not in J_op]:
            #         e = np.array([1 if i==s else 0 for i in range(n)], dtype=np.float64)
            #         if np.dot(np.dot(e, reversal_matrix(A_op)), A[:, j_plus]) > 0.0001:
            #             has_not_null = True
            #             break
            #     if has_not_null:
            #         break
            # if has_not_null is not None and has_not_null:  # c

            if new_j != -1:
                print 'c'
                J_op.remove(j_star)
                J_op.append(new_j)
                J_star.remove(j_star)
                min_delta += min_teta * delta__
                pass_step_first = True
            else:  # d
                print 'd'
                J_op.remove(j_star)
                J_op.append(j0)
                J_star.remove(j_star)
                J_star.append(j0)
                pass_step_first = False
        print J_star, J_op
        print '--------'
    return x0
コード例 #28
0
ファイル: test_reversal_matrix.py プロジェクト: kavaliou/MOiU
 def test_1(self):
     c1 = np.array([1, 2, 2, 4, 1, 2, 4, 2, 3], dtype=np.float).reshape((3, 3))
     answer1 = [[1, 2, -2],
                [4, 5, -6],
                [-4, -6, 7]]
     np.testing.assert_array_almost_equal(np.array(reversal_matrix(c1)), np.array(answer1))
コード例 #29
0
def simplex_method(A, b, C, x0=None, J_b=None):
    n = len(C)
    assert x0 is not None or J_b is not None
    if J_b is None:
        J_b = [num for num, i in enumerate(x0) if i]
    J_nb = [j for j in xrange(n) if j not in J_b]
    A_basis = np.array([A[:, j] for j in J_b]).transpose()
    B = reversal_matrix(A_basis)
    if x0 is None:
        x0 = [0] * n
        for num, i in enumerate(np.dot(B, b)):
            x0[J_b[num]] = i





    while True:

        c_basis = [C[j] for j in J_b]
        u__ = np.dot(c_basis, B)

        deltas = {j: np.dot(u__, A[:, j]) - C[j] for j, x in enumerate(x0) if not x}

        deltas = np.dot(u__, A) - C

        negative_deltas = filter(lambda delta: delta[1] < 0, filter(lambda x: x[0] in J_nb, enumerate(deltas)))

        if not negative_deltas:
            return x0  # WIN

        delta = min([(nd[1], nd[0]) for nd in negative_deltas])
        j0 = delta[1]
        z = np.dot(B, A[:, j0])

        assert any([zi > 0 for zi in z])

        psi, s = min((x0[J_b[i]] / z[i], i) for i in xrange(len(J_b)) if z[i] > 0)

        # x_s = [x for x in x0 if x]
        # psi = min([x_s[num]/zi for num, zi in enumerate(z) if zi > 0])
        # s = [num for num, zi in enumerate(z) if x_s[num]/zi == psi and zi > 0][0]

        js = J_b[s]

        for j in J_nb:
            x0[j] = 0

        x0[j0] = psi

        for num, j in enumerate(J_b):
            x0[j] -= psi * z[num]

        J_b[s] = j0
        for i in xrange(len(J_nb)):
            if J_nb[i] == j0:
                J_nb[i] = js
                break

        d = z.copy()
        z_s = d[s]
        d[s] = -1
        d /= -1 * z_s
        M = get_unit_matrix(d.shape[0])
        M[:, s] = d
        B = np.dot(M, B)