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
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
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
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)
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
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
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)
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))
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))
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))
def test_7(self): c7 = [[0, 2, 3], [0, 1, 1], [0, 1, 1]] with self.assertRaises(ValueError): reversal_matrix(c7)
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
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))
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))
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]
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'
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'
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 ]
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))
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))
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))
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
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))
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)