def modelisation(): # Variables m, L, li, qi = read_instance_file(argv[1]) # Modèle pour résoudre le problème de minimisation des planches utilisées model = Cplex() model.set_results_stream(None) # Variables de décision du modèle model_variables = list(range(len(li))) model.variables.add(obj=[1 for j in model_variables]) # Contraintes du modèle model_contraintes = range(len(qi)) model.linear_constraints.add( lin_expr=[SparsePair() for j in model_contraintes], senses=["G" for j in model_contraintes], rhs=qi) for var_index in model_variables: model.linear_constraints.set_coefficients(var_index, var_index, int(L / li[var_index])) # Modèle utilisé pour générer des pattern en utilisant # la méthode Column generation de Gilmore-Gomory pattern_model = Cplex() pattern_model.set_results_stream(None) # Variable de décision panneaux_indices = range(len(li)) pattern_model.variables.add( types=[pattern_model.variables.type.integer for j in panneaux_indices]) pattern_model.variables.add(obj=[1], lb=[1], ub=[1]) # L'unique contrainte ici est que la taille total des panneaux ne peut être # plus grande que la longueur de la planche L. pattern_model.linear_constraints.add( lin_expr=[SparsePair(ind=panneaux_indices, val=li)], senses=["L"], rhs=[L]) # Définir l'objectif (Minimisation) pattern_model.objective.set_sense(pattern_model.objective.sense.minimize) return m, model, pattern_model, model_contraintes, model_variables, panneaux_indices
def test_penalize_binary(self): op = OptimizationProblem() op.variables.add(names=['x', 'y', 'z'], types='B' * 3) op.linear_constraints.add(lin_expr=[ SparsePair(ind=['x', 'y'], val=[1, 1]), SparsePair(ind=['y', 'z'], val=[1, -1]) ], senses=['E', 'E'], rhs=[1, 2], names=['xy', 'yz']) self.assertEqual(op.linear_constraints.get_num(), 2) conv = PenalizeLinearEqualityConstraints() op2 = conv.encode(op) self.assertEqual(op2.linear_constraints.get_num(), 0)
def test_penalize_sense(self): op = OptimizationProblem() op.variables.add(names=['x', 'y', 'z'], types='B' * 3) op.linear_constraints.add(lin_expr=[ SparsePair(ind=['x', 'y'], val=[1, 1]), SparsePair(ind=['y', 'z'], val=[1, -1]), SparsePair(ind=['z', 'x'], val=[1, 2]) ], senses=['E', 'L', 'G'], rhs=[1, 2, 3], names=['xy', 'yz', 'zx']) self.assertEqual(op.linear_constraints.get_num(), 3) conv = PenalizeLinearEqualityConstraints() self.assertRaises(QiskitOptimizationError, lambda: conv.encode(op))
def test_add(self): op = OptimizationProblem() op.variables.add(names=["x1", "x2", "x3"]) op.linear_constraints.add(lin_expr=[ SparsePair(ind=["x1", "x3"], val=[1.0, -1.0]), SparsePair(ind=["x1", "x2"], val=[1.0, 1.0]), SparsePair(ind=["x1", "x2", "x3"], val=[-1.0] * 3), SparsePair(ind=["x2", "x3"], val=[10.0, -2.0]) ], senses=["E", "L", "G", "R"], rhs=[0.0, 1.0, -1.0, 2.0], range_values=[0.0, 0.0, 0.0, -10.0], names=["c0", "c1", "c2", "c3"]) self.assertListEqual(op.linear_constraints.get_rhs(), [0.0, 1.0, -1.0, 2.0])
def inout1(): c = cplex.Cplex() # sys.stdout is the default output stream for log and results # so these lines may be omitted c.set_results_stream(sys.stdout) c.set_log_stream(sys.stdout) # indices of the inside production variables inside = list(range(0, nbProducts)) c.variables.add(lb=[0 for x in inside], names=["inside_" + str(i) for i in range(nbProducts)], obj=insideCost) # indices of the outside production variables outside = list(range(nbProducts, 2 * nbProducts)) c.variables.add(lb=[0.0 for x in outside], names=["outside_" + str(i) for i in range(nbProducts)], obj=outsideCost) # add capacity constraint for each resource c.linear_constraints.add( lin_expr=[ SparsePair(ind=inside, val=consumption[i]) for i in range(len(consumption)) ], senses=["L" for i in consumption], rhs=capacity, names=["capacity_" + str(i) for i in range(nbResources)]) # must meet demand for each product c.linear_constraints.add( lin_expr=[ SparsePair(ind=[inside[p]] + [outside[p]], val=[1.0 for i in [0, 1]]) for p in range(nbProducts) ], senses=["E" for i in demand], rhs=demand, names=["demand_" + str(i) for i in range(nbProducts)]) # find cost-minimal solution c.solve() print("Solution status = ", c.solution.get_status()) print("cost: " + str(c.solution.get_objective_value())) for p in range(nbProducts): print("Product ", p, ":") print(" inside: ", c.solution.get_values(inside[p])) print(" outside: ", c.solution.get_values(outside[p]))
def _add_continuous_slack_var_constraint(self, name, row, rhs, sense): slack_name = name + self._delimiter + 'continuous_slack' lhs_lb, lhs_ub = self._calc_bounds(row) if sense == 'L': sign = 1 self._dst.variables.add(names=[slack_name], lb=[0], ub=[rhs - lhs_lb], types=['C']) elif sense == 'G': sign = -1 self._dst.variables.add(names=[slack_name], lb=[0], ub=[lhs_ub - rhs], types=['C']) else: raise QiskitOptimizationError('Type of Sense in ' + name + 'is not supported') self._conv[name] = slack_name new_ind = copy.deepcopy(row.ind) new_val = copy.deepcopy(row.val) new_ind.append(self._dst.variables.get_indices(slack_name)) new_val.append(sign) # Add a new equality constraint. self._dst.linear_constraints.add( lin_expr=[SparsePair(ind=new_ind, val=new_val)], senses=['E'], rhs=[rhs], names=[name])
def test_initial2(self): op = OptimizationProblem() op.variables.add(names=['x1', 'x2', 'x3'], types='B' * 3) c = op.quadratic_constraints.add(lin_expr=SparsePair(ind=['x1', 'x3'], val=[1.0, -1.0]), quad_expr=SparseTriple( ind1=['x1', 'x2'], ind2=['x2', 'x3'], val=[1.0, -1.0]), sense='E', rhs=1.0) quad = op.quadratic_constraints self.assertEqual(quad.get_num(), 1) self.assertListEqual(quad.get_names(), ['q0']) self.assertListEqual(quad.get_rhs(), [1.0]) self.assertListEqual(quad.get_senses(), ['E']) self.assertListEqual(quad.get_linear_num_nonzeros(), [2]) self.assertListEqual(quad.get_quad_num_nonzeros(), [2]) l = quad.get_linear_components() self.assertEqual(len(l), 1) self.assertListEqual(l[0].ind, [0, 2]) self.assertListEqual(l[0].val, [1.0, -1.0]) q = quad.get_quadratic_components() self.assertEqual(len(q), 1) self.assertListEqual(q[0].ind1, [1, 2]) self.assertListEqual(q[0].ind2, [0, 1]) self.assertListEqual(q[0].val, [1.0, -1.0])
def cast_mip_start(mip_start, cpx): """ casts the solution values and indices in a Cplex SparsePair Parameters ---------- mip_start cplex SparsePair cpx Cplex Returns ------- Cplex SparsePair where the indices are integers and the values for each variable match the variable type specified in CPLEX Object """ assert isinstance(cpx, Cplex) assert isinstance(mip_start, SparsePair) vals = list(mip_start.val) idx = np.array(list(mip_start.ind), dtype = int).tolist() types = cpx.variables.get_types(idx) for j, t in enumerate(types): if t in ['B', 'I']: vals[j] = int(vals[j]) elif t in ['C']: vals[j] = float(vals[j]) return SparsePair(ind = idx, val = vals)
def test_get_num_nonzeros(self): op = OptimizationProblem() op.variables.add(names=["x1", "x2", "x3"]) op.linear_constraints.add(names=["c0", "c1", "c2", "c3"], lin_expr=[ SparsePair(ind=["x1", "x3"], val=[1.0, -1.0]), SparsePair(ind=["x1", "x2"], val=[1.0, 1.0]), SparsePair(ind=["x1", "x2", "x3"], val=[-1.0] * 3), SparsePair(ind=["x2", "x3"], val=[10.0, -2.0]) ]) self.assertEqual(op.linear_constraints.get_num_nonzeros(), 9) op.linear_constraints.set_coefficients("c0", "x3", 0) self.assertEqual(op.linear_constraints.get_num_nonzeros(), 8)
def _create_constraint_capacity(self) -> None: self.op.linear_constraints.add(lin_expr=[ SparsePair( ind=[self._var_name("x", i, j) for i, j in self.range_x_vars], val=[self.resource_values[i, j] for i, j in self.range_x_vars]) ], senses="L", rhs=[self.knapsack_capacity], names=["CAPACITY"])
def test_inequality_binary(self): op = OptimizationProblem() op.variables.add(names=['x', 'y', 'z'], types='B' * 3) op.linear_constraints.add(lin_expr=[ SparsePair(ind=['x', 'y'], val=[1, 1]), SparsePair(ind=['y', 'z'], val=[1, -1]), SparsePair(ind=['z', 'x'], val=[1, 2]) ], senses=['E', 'L', 'G'], rhs=[1, 2, 3], names=['xy', 'yz', 'zx']) conv = InequalityToEqualityConverter() op2 = conv.encode(op) self.assertEqual(op.get_problem_name(), op2.get_problem_name()) self.assertEqual(op.get_problem_type(), op2.get_problem_type()) cst = op2.linear_constraints self.assertListEqual(cst.get_names(), ['xy', 'yz', 'zx']) self.assertListEqual(cst.get_senses(), ['E', 'E', 'E']) self.assertListEqual(cst.get_rhs(), [1, 2, 3])
def test_add(self): op = OptimizationProblem() op.variables.add(names=['x', 'y']) l = SparsePair(ind=['x'], val=[1.0]) q = SparseTriple(ind1=['x'], ind2=['y'], val=[1.0]) self.assertEqual( op.quadratic_constraints.add(name='my quad', lin_expr=l, quad_expr=q, rhs=1.0, sense='G'), 0)
def add_sos(self, coef): """ :type coef: list[(int, float)] """ ind, val = self._convert_coefficients(coef) c = {'type': '1', 'SOS': SparsePair(ind, val), 'name': 'sos' + str(self._model.SOS.get_num()), } self._model.SOS.add(**c)
def test_get_rows(self): op = OptimizationProblem() op.variables.add(names=["x1", "x2", "x3"]) op.linear_constraints.add(names=["c0", "c1", "c2", "c3"], lin_expr=[ SparsePair(ind=["x1", "x3"], val=[1.0, -1.0]), SparsePair(ind=["x1", "x2"], val=[1.0, 1.0]), SparsePair(ind=["x1", "x2", "x3"], val=[-1.0] * 3), SparsePair(ind=["x2", "x3"], val=[10.0, -2.0]) ]) sp = op.linear_constraints.get_rows(0) self.assertListEqual(sp.ind, [0, 2]) self.assertListEqual(sp.val, [1.0, -1.0]) sp = op.linear_constraints.get_rows(1, 3) self.assertListEqual(sp[0].ind, [0, 1]) self.assertListEqual(sp[0].val, [1.0, 1.0]) self.assertListEqual(sp[1].ind, [0, 1, 2]) self.assertListEqual(sp[1].val, [-1.0, -1.0, -1.0]) self.assertListEqual(sp[2].ind, [1, 2]) self.assertListEqual(sp[2].val, [10.0, -2.0]) sp = op.linear_constraints.get_rows(['c2', 0]) self.assertListEqual(sp[0].ind, [0, 1, 2]) self.assertListEqual(sp[0].val, [-1.0, -1.0, -1.0]) self.assertListEqual(sp[1].ind, [0, 2]) self.assertListEqual(sp[1].val, [1.0, -1.0]) sp = op.linear_constraints.get_rows() self.assertListEqual(sp[0].ind, [0, 2]) self.assertListEqual(sp[0].val, [1.0, -1.0]) self.assertListEqual(sp[1].ind, [0, 1]) self.assertListEqual(sp[1].val, [1.0, 1.0]) self.assertListEqual(sp[2].ind, [0, 1, 2]) self.assertListEqual(sp[2].val, [-1.0, -1.0, -1.0]) self.assertListEqual(sp[3].ind, [1, 2]) self.assertListEqual(sp[3].val, [10.0, -2.0])
def test_get_num(self): op = OptimizationProblem() op.variables.add(names=['x', 'y']) l = SparsePair(ind=['x'], val=[1.0]) q = SparseTriple(ind1=['x'], ind2=['y'], val=[1.0]) n = 10 for i in range(n): self.assertEqual( op.quadratic_constraints.add(name=str(i), lin_expr=l, quad_expr=q), i) self.assertEqual(op.quadratic_constraints.get_num(), n)
def _create_constraint_allocation(self) -> None: self.op.linear_constraints.add(lin_expr=[ SparsePair(ind=[self._var_name("x", k, t)] + [self._var_name("y", k)], val=[1.0, -1.0]) for k, t in self.range_x_vars ], senses="L" * self.n_x_vars, rhs=[0.0] * self.n_x_vars, names=[ self._var_name("ALLOCATION", k, t) for k, t in self.range_x_vars ])
def test_set_quadratic(self): op = OptimizationProblem() n = 3 op.variables.add(names=[str(i) for i in range(n)]) obj = op.objective obj.set_quadratic([SparsePair(ind=[0, 1, 2], val=[1.0, -2.0, 0.5]), ([0, 1], [-2.0, -1.0]), SparsePair(ind=[0, 2], val=[0.5, -3.0])]) lst = obj.get_quadratic(range(n)) self.assertListEqual(lst[0].ind, [0, 1, 2]) self.assertListEqual(lst[0].val, [1.0, -2.0, 0.5]) self.assertListEqual(lst[1].ind, [0, 1]) self.assertListEqual(lst[1].val, [-2.0, -1.0]) self.assertListEqual(lst[2].ind, [0, 2]) self.assertListEqual(lst[2].val, [0.5, -3.0]) obj.set_quadratic([1.0, 2.0, 3.0]) lst = obj.get_quadratic(range(n)) self.assertListEqual(lst[0].ind, [0]) self.assertListEqual(lst[0].val, [1.0]) self.assertListEqual(lst[1].ind, [1]) self.assertListEqual(lst[1].val, [2.0]) self.assertListEqual(lst[2].ind, [2]) self.assertListEqual(lst[2].val, [3.0])
def _add_int_slack_var_constraint(self, name, row, rhs, sense): # If a coefficient that is not integer exist, raise error if any( isinstance(coef, float) and not coef.is_integer() for coef in row.val): raise QiskitOptimizationError('Can not use a slack variable for ' + name) slack_name = name + self._delimiter + 'int_slack' lhs_lb, lhs_ub = self._calc_bounds(row) # If rhs is float number, round up/down to the nearest integer. if sense == 'L': new_rhs = math.floor(rhs) if sense == 'G': new_rhs = math.ceil(rhs) # Add a new integer variable. if sense == 'L': sign = 1 self._dst.variables.add(names=[slack_name], lb=[0], ub=[new_rhs - lhs_lb], types=['I']) elif sense == 'G': sign = -1 self._dst.variables.add(names=[slack_name], lb=[0], ub=[lhs_ub - new_rhs], types=['I']) else: raise QiskitOptimizationError('The type of Sense in ' + name + 'is not supported') self._conv[name] = slack_name new_ind = copy.deepcopy(row.ind) new_val = copy.deepcopy(row.val) new_ind.append(self._dst.variables.get_indices(slack_name)) new_val.append(sign) # Add a new equality constraint. self._dst.linear_constraints.add( lin_expr=[SparsePair(ind=new_ind, val=new_val)], senses=['E'], rhs=[new_rhs], names=[name])
def test_cobyla_optimizer_with_quadratic_constraint(self): """ Cobyla Optimizer Test """ # load optimization problem problem = OptimizationProblem() problem.variables.add(lb=[0, 0], ub=[1, 1], types='CC') problem.objective.set_linear([(0, 1), (1, 1)]) qc = problem.quadratic_constraints linear = SparsePair(ind=[0, 1], val=[-1, -1]) quadratic = SparseTriple(ind1=[0, 1], ind2=[0, 1], val=[1, 1]) qc.add(name='qc', lin_expr=linear, quad_expr=quadratic, rhs=-1/2) # solve problem with cobyla result = self.cobyla_optimizer.solve(problem) # analyze results self.assertAlmostEqual(result.fval, 1.0, places=2)
def add_linear_constraint(self, coef, sense, rhs): """ Args: coef (list[(int, float)]): coef sense (str): sense rhs (float): rhs """ if not coef: logger.warning('empty linear constraint') return ind, val = self._convert_coefficients(coef) sense = self._convert_sense(sense) c = self._lin c['lin_expr'].append(SparsePair(ind, val)) c['senses'].append(sense) c['rhs'].append(rhs) c['range_values'].append(0) c['names'].append('c' + str(len(self._lin['names'])))
def remove_feature_combination(self): mip = self.mip u_names = self.mip_indices['action_off_names'] u = np.array(mip.solution.get_values(u_names)) on_idx = np.isclose(u, 0.0) n = len(u_names) con_vals = np.ones(n, dtype=np.float_) con_vals[on_idx] = -1.0 con_rhs = n - 1 - np.sum(on_idx) mip.linear_constraints.add( lin_expr=[SparsePair(ind=u_names, val=con_vals.tolist())], senses=["L"], rhs=[float(con_rhs)]) return
def add_linear_constraint(self, coef, sense, rhs): """ :type coef: list[(int, float)] :type sense: string :type rhs: float :rtype: None """ if not coef: logger.warning('empty linear constraint') return ind, val = self._convert_coefficients(coef) sense = self._convert_sense(sense) c = self._lin c['lin_expr'].append(SparsePair(ind, val)) c['senses'].append(sense) c['rhs'].append(rhs) c['range_values'].append(0) c['names'].append('c' + str(len(self._lin['names'])))
def add_cuts(problem, cuts): """Add cuts to a Cplex problem. Parameters ---------- problem : cplex.Cplex LP to which cuts should be added. cuts : List[CutData] Cuts to be added. """ # Add new cuts to the master for cut in cuts: lp_cut = SparsePair(ind=cut.indices, val=cut.elements) problem.linear_constraints.add(lin_expr=[lp_cut], senses=[cut.sense], rhs=[cut.rhs], names=[cut.name])
def test_set_linear_components(self): op = OptimizationProblem() op.linear_constraints.add(names=["c0", "c1", "c2", "c3"]) op.variables.add(names=["x0", "x1"]) op.linear_constraints.set_linear_components("c0", [["x0"], [1.0]]) sp = op.linear_constraints.get_rows("c0") self.assertListEqual(sp.ind, [0]) self.assertListEqual(sp.val, [1.0]) op.linear_constraints.set_linear_components([("c3", SparsePair(ind=["x1"], val=[-1.0])), (2, [[0, 1], [-2.0, 3.0]])]) sp = op.linear_constraints.get_rows("c3") self.assertListEqual(sp.ind, [1]) self.assertListEqual(sp.val, [-1.0]) sp = op.linear_constraints.get_rows(2) self.assertListEqual(sp.ind, [0, 1]) self.assertListEqual(sp.val, [-2.0, 3.0])
def add_indicator_constraint(self, indvar, complemented, coef, sense, rhs): """ Args: indvar (int): ind var complemented (int): complemented coef (list[(int, float)]): coef sense (str): sense rhs (float): rhs """ ind, val = self._convert_coefficients(coef) sense = self._convert_sense(sense) c = {'lin_expr': SparsePair(ind, val), 'sense': sense, 'rhs': rhs, 'name': 'i' + str(self._model.indicator_constraints.get_num()), 'indvar': indvar, 'complemented': complemented } self._model.indicator_constraints.add(**c)
def add_indicator_constraint(self, indvar, complemented, coef, sense, rhs): """ :type indvar: int :type complemented: int :type coef: list[(int, float)] :type sense: string :type rhs: float :rtype: None """ ind, val = self._convert_coefficients(coef) sense = self._convert_sense(sense) c = {'lin_expr': SparsePair(ind, val), 'sense': sense, 'rhs': rhs, 'name': 'i' + str(self._model.indicator_constraints.get_num()), 'indvar': indvar, 'complemented': complemented } self._model.indicator_constraints.add(**c)
def add_quadratic_constraint(self, lin, quad, sense, rhs): """ Args: lin (list[(int, float)]): lin quad (list[(int, int, float)]): quad sense (str): sense rhs (float): rhs """ ind, val = self._convert_coefficients(lin) ind1 = [e[0] for e in quad] ind2 = [e[1] for e in quad] val2 = [e[2] for e in quad] sense = self._convert_sense(sense) c = {'lin_expr': SparsePair(ind, val), 'quad_expr': SparseTriple(ind1, ind2, val2), 'sense': sense, 'rhs': rhs, 'name': 'q' + str(self._model.quadratic_constraints.get_num()) } self._model.quadratic_constraints.add(**c)
def add_quadratic_constraint(self, lin, quad, sense, rhs): """ :type lin: list[(int, float)] :type quad: list[(int, int, float)] :type sense: string :type rhs: float :rtype: None """ ind, val = self._convert_coefficients(lin) ind1 = [e[0] for e in quad] ind2 = [e[1] for e in quad] val2 = [e[2] for e in quad] sense = self._convert_sense(sense) c = {'lin_expr': SparsePair(ind, val), 'quad_expr': SparseTriple(ind1, ind2, val2), 'sense': sense, 'rhs': rhs, 'name': 'q' + str(self._model.quadratic_constraints.get_num()) } self._model.quadratic_constraints.add(**c)
def add_constraints(self, constr_ids, lhs, senses, rhs): """ Add a list of constraints to the current problem. Arguments: constr_ids (list): constraint identifiers lhs (list): variables and respective coefficients senses (list): constraint senses (default: '=') rhs (list): right-hand side of equations (default: 0) """ map_sense = {'=': 'E', '<': 'L', '>': 'G'} exprs = [SparsePair(ind=list(constr.keys()), val=list(constr.values())) for constr in lhs] senses = [map_sense[sense] for sense in senses] self.problem.linear_constraints.add(lin_expr=exprs, senses=senses, rhs=rhs, names=constr_ids) self.constr_ids.extend(constr_ids)
def add_mip_start(cpx, solution, effort_level=1, name=None): """ :param cpx: :param solution: :param effort_level: (must be one of the values of mip.MIP_starts.effort_level) 1 <-> check_feasibility 2 <-> solve_fixed 3 <-> solve_MIP 4 <-> repair 5 <-> no_check :param name: :return: mip """ if isinstance(solution, np.ndarray): solution = solution.tolist() mip_start = SparsePair(val=solution, ind=list(range(len(solution)))) if name is None: cpx.MIP_starts.add(mip_start, effort_level) else: cpx.MIP_starts.add(mip_start, effort_level, name) return cpx