def build_dual_from_max_primal(self) -> LinearModel: # Building FO variables = [] fo_coefficients = [i[0] for i in self.primal.b] fo_coefficients_variables = [] for index, c in enumerate(self.primal.constraints): var = None if c.equality_operator == '<=': var = Variable(name='y{0}'.format(index + 1), initial_index=index) elif c.equality_operator == '>=': var = Variable(name='y{0}'.format(index + 1), initial_index=index, constraint=VariableConstraint.Negative) elif c.equality_operator == '=': var = Variable(name='y{0}'.format(index + 1), initial_index=index, constraint=VariableConstraint.Unrestricted) variables.append(var) fo_coefficients_variables.append((fo_coefficients[index], var)) fo = ObjectiveFunction('min', fo_coefficients_variables) # Building Constraints constraints_inequalities = [] for v in self.primal.fo.variables: if v.non_positive: constraints_inequalities.append('<=') elif v.free: constraints_inequalities.append('=') else: constraints_inequalities.append('>=') constraints = [] At = self.primal.A.transpose() right_side = self.primal.fo.coefficients _i = 0 for row in At: const_coefficients_variables = [] for index, v in enumerate(variables): const_coefficients_variables.append((row[index], v)) constraint = Constraint( name='R{0}'.format(_i + 1), coefficients_variables=const_coefficients_variables, equality_operator=constraints_inequalities[_i], right_side=right_side[_i]) constraints.append(constraint) _i = _i + 1 return LinearModel(objective_function=fo, constraints_list=constraints, name=self.primal.name + '- Dual')
variable_leave_B = solver.B_variables[variable_leave_B_index] variable_join_N = solver.N_variables[variable_join_N_index] solver.B_variables[variable_leave_B_index] = variable_join_N solver.N_variables[variable_join_N_index] = variable_leave_B self.current_iteration = self.current_iteration + 1 self.__solve_lp__(__solver__=solver) if __name__ == '__main__': x1 = Variable(name='x1') x2 = Variable(name='x2') x3 = Variable(name='x3') fo = ObjectiveFunction('min', [(1, x1), (-1, x2), (2, x3)]) c1 = Constraint([(1, x1), (1, x2), (1, x3)], '=', 3) c2 = Constraint([(2, x1), (-1, x2), (3, x3)], '<=', 4) model = LinearModel(objective_function=fo, constraints_list=[c1, c2]) p1 = Phase1(linear_model=model) initial_base = p1.find_base() p2 = Phase2(linear_model=model, base_indexes=p1.base_variables) p2.solve() print('Phase1 unit test passed')
def branch_and_bound(self): # Relaxed Solution relaxed_solution = self.solve_two_phase(self.model) relaxed_branch = Branch(relaxed_solution) if relaxed_branch.has_only_integers or not relaxed_branch.needs_branching or len( relaxed_branch.needs_branching) <= 0: self.solution = relaxed_solution self.best_solution = relaxed_solution print( '[WARNING]: Branch and Bound relaxed solution only contained integers.' ) return # Global variables possible_solutions = [] global_fo = 0 best_solution = None base_constraints = self.model.constraints iteration = 0 has_finished = False # Branch and Bound v = relaxed_branch.variable_to_branch needs_further_branching = [] loop_constraints = base_constraints parent_branch = relaxed_branch __i__ = 1 while not has_finished: coefficients_variables = [ (0, _v[1]) if _v[1].id != parent_branch.variable_to_branch[1].id else (1, _v[1]) for _v in parent_branch.solution.decision_variables ] lower_bound = floor(v[0]) upper_bound = ceil(v[0]) c_down = Constraint(coefficients_variables, '<=', lower_bound) c_up = Constraint(coefficients_variables, '>=', upper_bound) const_down = deepcopy(loop_constraints) const_up = deepcopy(loop_constraints) const_down.append(c_down) const_up.append(c_up) l_down = LinearModel(objective_function=self.model.fo, constraints_list=const_down, name='Branch {0}'.format(iteration)) iteration = iteration + 1 l_up = LinearModel(objective_function=self.model.fo, constraints_list=const_up, name='Branch {0}'.format(iteration)) iteration = iteration + 1 s_up = self.solve_two_phase(l_up) s_down = self.solve_two_phase(l_down) b_down = Branch(solution=s_down) b_down.constraints = const_down parent_branch.children.append(b_down) b_up = Branch(solution=s_up) b_up.constraints = const_up parent_branch.children.append(b_up) if b_down.feasible: if b_down.feasible and b_down.has_only_integers: possible_solutions.append(b_down) if b_down.fo_value > global_fo: global_fo = b_down.fo_value best_solution = b_down else: needs_further_branching.append(b_down) if b_up.feasible: if b_up.has_only_integers: possible_solutions.append(b_up) if b_up.fo_value > global_fo: global_fo = b_up.fo_value best_solution = b_up else: needs_further_branching.append(b_up) if needs_further_branching and len(needs_further_branching) > 0: needs_further_branching = sorted(needs_further_branching, key=lambda _b: _b.fo_value, reverse=True) possible_next_branch = needs_further_branching[0] if possible_next_branch.fo_value > global_fo: v = possible_next_branch.variable_to_branch loop_constraints = possible_next_branch.constraints needs_further_branching.pop(0) parent_branch = possible_next_branch __i__ += 1 else: has_finished = True self.branch_tree = BranchTree(root_branch=relaxed_branch) self.best_solution = best_solution self.all_solutions = possible_solutions else: has_finished = True self.branch_tree = BranchTree(root_branch=relaxed_branch) self.best_solution = best_solution self.all_solutions = possible_solutions
@property def simplex_multiplierT(self): return np.dot(self.CbT, self.B_inv) @property def CbT(self): return [self.model.fo.coefficients[i] for i in self.B_variables] @property def CnT(self): return [self.model.fo.coefficients[i] for i in self.N_variables] @property def fo_value(self): return np.dot(self.CbT, self.xb) if __name__ == '__main__': from models.variable import Variable from models.function import ObjectiveFunction, Constraint from models.phase1 import Phase1 x1 = Variable(name='x1') x2 = Variable(name='x2') fo = ObjectiveFunction('min', [(80, x1), (60, x2)]) c1 = Constraint([(1, x1), (1, x2)], '>=', 1) c2 = Constraint([(-0.05, x1), (0.07, x2)], '<=', 0) model = LinearModel(objective_function=fo, constraints_list=[c1, c2]) p1 = Phase1(linear_model=model) solver = SimplexSolver(linear_model=p1.model, base_variables=[3, 4], non_base_variables=[0, 1, 2]) print('Simplex Solver test passed')
_i = 0 for row in At: const_coefficients_variables = [] for index, v in enumerate(variables): const_coefficients_variables.append((row[index], v)) constraint = Constraint( name='R{0}'.format(_i + 1), coefficients_variables=const_coefficients_variables, equality_operator=constraints_inequalities[_i], right_side=right_side[_i]) constraints.append(constraint) _i = _i + 1 return LinearModel(objective_function=fo, constraints_list=constraints, name=self.primal.name + '- Dual') if __name__ == '__main__': x1 = Variable(name='x1') x2 = Variable(name='x2', constraint=VariableConstraint.Unrestricted) x3 = Variable(name='x3', constraint=VariableConstraint.Negative) fo = ObjectiveFunction('max', [(1, x1), (2, x2), (0, x3)]) c1 = Constraint([(-2, x1), (1, x2), (1, x3)], '>=', 3) c2 = Constraint([(3, x1), (4, x2)], '<=', 5) primal = LinearModel(objective_function=fo, constraints_list=[c1, c2]) dual_transformation = DualTransformation(primal=primal) dual = dual_transformation.dual print('Dual unit test passed')
@property def b(self): _b = np.zeros(shape=(self.m, 1)) for index, c in enumerate(self.constraints): _b[index] = c.right_side return _b def __repr__(self): m = '\nModel {0}:\n'.format(self.name) m = m + 'min Fo(x)= ' for index, v in enumerate(self.fo.variables): m = m + str(self.fo.coefficients[index]) + '*' + str(v) + ' ' m = m + '\n\n' for r in self.constraints: m = m + str(r) + '\n' return m if __name__ == '__main__': x1 = Variable(name='x1') x2 = Variable(name='x2', negative=True) x3 = Variable(name='x3', free=True) x4 = Variable(name='x4', free=True) fo = ObjectiveFunction('max', [(3, x1), (2, x2), (-1, x3), (1, x4)]) c1 = Constraint([(1, x1), (2, x2), (1, x3), (-1, x4)], '<=', 5) c2 = Constraint([(-2, x1), (-4, x2), (1, x3), (1, x4)], '<=', -1) model = LinearModel(objective_function=fo, constraints_list=[c1, c2]) model.standard_form() print('Linear Model unit test passed')
from models.variable import Variable, VariableConstraint from models.function import ObjectiveFunction, Constraint from models.linear_model import LinearModel from models.solver import LinearSolver # Problem setup Branch and Bound x1 = Variable(name='x1', integer=True) x2 = Variable(name='x2', integer=True) fo = ObjectiveFunction('max', [(3, x1), (5, x2)]) c1 = Constraint([(2, x1), (4, x2)], '<=', 25) c2 = Constraint([(1, x1)], '<=', 8) c3 = Constraint([(2, x2)], '<=', 10) model = LinearModel(objective_function=fo, constraints_list=[c1, c2, c3]) solver = LinearSolver(linear_model=model) print(solver.best_solution) """ # Problem setup (Branch and Bound with degeneracy x1 = Variable(name='x1', integer=True) x2 = Variable(name='x2', integer=True) fo = ObjectiveFunction('max', [(3, x1), (7, x2)]) c1 = Constraint([(1, x1)], '<=', 3.5) c2 = Constraint([(5, x1), (-4, x2)], '<=', 10) c3 = Constraint([(4/7, x1), (2, x2)], '<=', 9) model = LinearModel(objective_function=fo, constraints_list=[c1, c2, c3]) solver = LinearSolver(linear_model=model) print(solver.best_solution) """