def test_penalize_integer(self): """ Test PenalizeLinearEqualityConstraints with integer variables """ op = QuadraticProgram() for i in range(3): op.integer_var(name='x{}'.format(i), lowerbound=-3, upperbound=3) # Linear constraints linear_constraint = {'x0': 1, 'x1': 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, 'x0x1') linear_constraint = {'x1': 1, 'x2': -1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 2, 'x1x2') linear_constraint = {'x0': 1, 'x2': -1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, 'x0x2') op.minimize(constant=3, linear={'x0': 1}, quadratic={('x1', 'x2'): 2}) self.assertEqual(op.get_num_linear_constraints(), 3) conv = LinearEqualityToPenalty() op2 = conv.convert(op) self.assertEqual(op2.get_num_linear_constraints(), 0) result = OptimizationResult(x=[0, 1, -1], fval=1, variables=op2.variables) new_result = conv.interpret(result) self.assertAlmostEqual(new_result.fval, 1) self.assertEqual(new_result.status, OptimizationResultStatus.SUCCESS) np.testing.assert_array_almost_equal(new_result.x, [0, 1, -1]) self.assertListEqual(result.variable_names, ['x0', 'x1', 'x2']) self.assertDictEqual(result.variables_dict, { 'x0': 0, 'x1': 1, 'x2': -1 })
def test_binary_to_integer(self): """ Test binary to integer """ op = QuadraticProgram() for i in range(0, 2): op.binary_var(name='x{}'.format(i)) op.integer_var(name='x2', lowerbound=0, upperbound=5) linear = {'x0': 1, 'x1': 2, 'x2': 1} op.maximize(0, linear, {}) linear = {} for x in op.variables: linear[x.name] = 1 op.linear_constraint(linear, Constraint.Sense.EQ, 6, 'x0x1x2') conv = IntegerToBinary() op2 = conv.convert(op) result = OptimizationResult(x=[0, 1, 1, 1, 1], fval=17, variables=op2.variables) new_result = conv.interpret(result) np.testing.assert_array_almost_equal(new_result.x, [0, 1, 5]) self.assertEqual(new_result.fval, 17) self.assertListEqual(new_result.variable_names, ['x0', 'x1', 'x2']) self.assertDictEqual(new_result.variables_dict, { 'x0': 0, 'x1': 1, 'x2': 5 })
def test_penalize_binary(self): """ Test PenalizeLinearEqualityConstraints with binary variables """ op = QuadraticProgram() for i in range(3): op.binary_var(name='x{}'.format(i)) # Linear constraints linear_constraint = {'x0': 1, 'x1': 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, 'x0x1') linear_constraint = {'x1': 1, 'x2': -1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 2, 'x1x2') linear_constraint = {'x0': 1, 'x2': 3} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 2, 'x0x2') self.assertEqual(op.get_num_linear_constraints(), 3) conv = LinearEqualityToPenalty() op2 = conv.convert(op) self.assertEqual(op2.get_num_linear_constraints(), 0) result = OptimizationResult(x=np.arange(3), fval=0, variables=op2.variables) new_result = conv.interpret(result) self.assertEqual(new_result.status, OptimizationResultStatus.INFEASIBLE) np.testing.assert_array_almost_equal(new_result.x, np.arange(3)) self.assertListEqual(result.variable_names, ['x0', 'x1', 'x2']) self.assertDictEqual(result.variables_dict, { 'x0': 0, 'x1': 1, 'x2': 2 })
def test_linear_equality_to_penalty_decode(self): """ Test decode func of LinearEqualityToPenalty""" qprog = QuadraticProgram() qprog.binary_var('x') qprog.binary_var('y') qprog.binary_var('z') qprog.maximize(linear={'x': 3, 'y': 1, 'z': 1}) qprog.linear_constraint(linear={'x': 1, 'y': 1, 'z': 1}, sense='EQ', rhs=2, name='xyz_eq') lineq2penalty = LinearEqualityToPenalty() qubo = lineq2penalty.convert(qprog) exact_mes = NumPyMinimumEigensolver() exact = MinimumEigenOptimizer(exact_mes) result = exact.solve(qubo) decoded_result = lineq2penalty.interpret(result) self.assertEqual(decoded_result.fval, 4) np.testing.assert_array_almost_equal(decoded_result.x, [1, 1, 0]) self.assertEqual(decoded_result.status, OptimizationResultStatus.SUCCESS) self.assertListEqual(decoded_result.variable_names, ['x', 'y', 'z']) self.assertDictEqual(decoded_result.variables_dict, {'x': 1.0, 'y': 1.0, 'z': 0.0}) infeasible_result = OptimizationResult(x=[1, 1, 1], fval=0, variables=qprog.variables, status=OptimizationResultStatus.SUCCESS) decoded_infeasible_result = lineq2penalty.interpret(infeasible_result) self.assertEqual(decoded_infeasible_result.fval, 5) np.testing.assert_array_almost_equal(decoded_infeasible_result.x, [1, 1, 1]) self.assertEqual(decoded_infeasible_result.status, OptimizationResultStatus.INFEASIBLE) self.assertListEqual(infeasible_result.variable_names, ['x', 'y', 'z']) self.assertDictEqual(infeasible_result.variables_dict, {'x': 1.0, 'y': 1.0, 'z': 1.0})
def multi_start_solve(self, minimize: Callable[[np.array], np.array], problem: QuadraticProgram) -> OptimizationResult: """Applies a multi start method given a local optimizer. Args: minimize: A callable object that minimizes the problem specified problem: A problem to solve Returns: The result of the multi start algorithm applied to the problem. """ fval_sol = INFINITY x_sol = None # type: Optional[np.array] # Implementation of multi-start optimizer for trial in range(self._trials): x_0 = np.zeros(problem.get_num_vars()) if trial > 0: for i, var in enumerate(problem.variables): lowerbound = var.lowerbound if var.lowerbound > -INFINITY else -self._clip upperbound = var.upperbound if var.upperbound < INFINITY else self._clip x_0[i] = uniform.rvs(lowerbound, (upperbound - lowerbound)) # run optimization t_0 = time.time() x = minimize(x_0) logger.debug("minimize done in: %s seconds", str(time.time() - t_0)) # we minimize, to get actual objective value we must multiply by the sense value fval = problem.objective.evaluate( x) * problem.objective.sense.value # we minimize the objective if fval < fval_sol: # here we get back to the original sense of the problem fval_sol = fval * problem.objective.sense.value x_sol = x return OptimizationResult(x_sol, fval_sol, x_sol, variables=problem.variables)
def test_binary_to_integer(self): """ Test binary to integer """ op = QuadraticProgram() for i in range(0, 2): op.binary_var(name='x{}'.format(i)) op.integer_var(name='x2', lowerbound=0, upperbound=5) linear = {} linear['x0'] = 1 linear['x1'] = 2 linear['x2'] = 1 op.maximize(0, linear, {}) linear = {} for x in op.variables: linear[x.name] = 1 op.linear_constraint(linear, Constraint.Sense.EQ, 6, 'x0x1x2') conv = IntegerToBinary() _ = conv.encode(op) result = OptimizationResult(x=[0, 1, 1, 1, 1], fval=17) new_result = conv.decode(result) self.assertListEqual(new_result.x, [0, 1, 5]) self.assertEqual(new_result.fval, 17)
def test_linear_equality_to_penalty_decode(self): """ Test decode func of LinearEqualityToPenalty""" qprog = QuadraticProgram() qprog .binary_var('x') qprog .binary_var('y') qprog .binary_var('z') qprog .maximize(linear={'x': 3, 'y': 1, 'z': 1}) qprog .linear_constraint(linear={'x': 1, 'y': 1, 'z': 1}, sense='EQ', rhs=2, name='xyz_eq') lineq2penalty = LinearEqualityToPenalty() qubo = lineq2penalty.encode(qprog) exact_mes = NumPyMinimumEigensolver() exact = MinimumEigenOptimizer(exact_mes) result = exact.solve(qubo) decoded_result = lineq2penalty.decode(result) self.assertEqual(decoded_result.fval, 4) self.assertListEqual(decoded_result.x, [1, 1, 0]) self.assertEqual(decoded_result.status, OptimizationResultStatus.SUCCESS) infeasible_result = OptimizationResult(x=[1, 1, 1]) decoded_infeasible_result = lineq2penalty.decode(infeasible_result) self.assertEqual(decoded_infeasible_result.fval, 5) self.assertListEqual(decoded_infeasible_result.x, [1, 1, 1]) self.assertEqual(decoded_infeasible_result.status, OptimizationResultStatus.INFEASIBLE)
def test_inequality_binary(self): """ Test InequalityToEqualityConverter with binary variables """ op = QuadraticProgram() for i in range(3): op.binary_var(name='x{}'.format(i)) # Linear constraints linear_constraint = {'x0': 1, 'x1': 1} op.linear_constraint(linear_constraint, Constraint.Sense.EQ, 1, 'x0x1') linear_constraint = {'x1': 1, 'x2': -1} op.linear_constraint(linear_constraint, Constraint.Sense.LE, 2, 'x1x2') linear_constraint = {'x0': 1, 'x2': 3} op.linear_constraint(linear_constraint, Constraint.Sense.GE, 2, 'x0x2') # Quadratic constraints quadratic = {('x0', 'x1'): 1, ('x1', 'x2'): 2} op.quadratic_constraint({}, quadratic, Constraint.Sense.LE, 3, 'x0x1_x1x2LE') quadratic = {('x0', 'x1'): 3, ('x1', 'x2'): 4} op.quadratic_constraint({}, quadratic, Constraint.Sense.GE, 3, 'x0x1_x1x2GE') # Convert inequality constraints into equality constraints conv = InequalityToEquality() op2 = conv.convert(op) self.assertListEqual([v.name for v in op2.variables], [ 'x0', 'x1', 'x2', 'x1x2@int_slack', 'x0x2@int_slack', 'x0x1_x1x2LE@int_slack', 'x0x1_x1x2GE@int_slack' ]) # Check names and objective senses self.assertEqual(op.name, op2.name) self.assertEqual(op.objective.sense, op2.objective.sense) # For linear constraints lst = [ op2.linear_constraints[0].linear.to_dict()[0], op2.linear_constraints[0].linear.to_dict()[1], ] self.assertListEqual(lst, [1, 1]) self.assertEqual(op2.linear_constraints[0].sense, Constraint.Sense.EQ) lst = [ op2.linear_constraints[1].linear.to_dict()[1], op2.linear_constraints[1].linear.to_dict()[2], op2.linear_constraints[1].linear.to_dict()[3], ] self.assertListEqual(lst, [1, -1, 1]) lst = [op2.variables[3].lowerbound, op2.variables[3].upperbound] self.assertListEqual(lst, [0, 3]) self.assertEqual(op2.linear_constraints[1].sense, Constraint.Sense.EQ) lst = [ op2.linear_constraints[2].linear.to_dict()[0], op2.linear_constraints[2].linear.to_dict()[2], op2.linear_constraints[2].linear.to_dict()[4], ] self.assertListEqual(lst, [1, 3, -1]) lst = [op2.variables[4].lowerbound, op2.variables[4].upperbound] self.assertListEqual(lst, [0, 2]) self.assertEqual(op2.linear_constraints[2].sense, Constraint.Sense.EQ) # For quadratic constraints lst = [ op2.quadratic_constraints[0].quadratic.to_dict()[(0, 1)], op2.quadratic_constraints[0].quadratic.to_dict()[(1, 2)], op2.quadratic_constraints[0].linear.to_dict()[5], ] self.assertListEqual(lst, [1, 2, 1]) lst = [op2.variables[5].lowerbound, op2.variables[5].upperbound] self.assertListEqual(lst, [0, 3]) lst = [ op2.quadratic_constraints[1].quadratic.to_dict()[(0, 1)], op2.quadratic_constraints[1].quadratic.to_dict()[(1, 2)], op2.quadratic_constraints[1].linear.to_dict()[6], ] self.assertListEqual(lst, [3, 4, -1]) lst = [op2.variables[6].lowerbound, op2.variables[6].upperbound] self.assertListEqual(lst, [0, 4]) result = OptimizationResult(x=np.arange(7), fval=0, variables=op2.variables) new_result = conv.interpret(result) np.testing.assert_array_almost_equal(new_result.x, np.arange(3)) self.assertListEqual(new_result.variable_names, ['x0', 'x1', 'x2']) self.assertDictEqual(new_result.variables_dict, { 'x0': 0, 'x1': 1, 'x2': 2 })