Exemplo n.º 1
0
def jsp_disjuntivo_manne(tempo, ordem, tempo_max=3600, fl_inteiro=True):
    if not jsp_checar_tempo_ordem(tempo, ordem):
        print("Matrizes de TEMPO e ORDEM incorretas!")

    # Criando parâmetros ######################################################
    # Número de máquinas e jobs
    m, n = jsp_get_dimensoes(tempo)

    # Criando conjunto de máquinas e jobs
    Maquinas = range(m)
    Jobs = range(n)
    ###########################################################################

    # Criando dicionario do Problema ##########################################
    Problema = montar_dic_problema(m, n, Maquinas, Jobs, tempo, ordem,
                                   fl_inteiro)
    ###########################################################################

    # Criando instancia do modelo #############################################
    modelo = Model(name='manne')
    modelo.parameters.timelimit = tempo_max
    ###########################################################################

    # Criando variáveis de decisão ############################################
    x = jsp_manne_var_x(modelo, Problema)  # início do job j na máquina i
    z = jsp_manne_var_z(modelo, Problema)  # 1 se j precede a k na máquina i
    cmax = jsp_manne_var_cmax(modelo, Problema)  # makespan
    y = None
    ###########################################################################

    # Restrições ##############################################################
    jsp_manne_rest_ordem_maq_job(modelo, x, z, cmax, y, Problema)
    jsp_manne_rest_precedencia(modelo, x, z, cmax, y, Problema)
    jsp_manne_rest_makespan(modelo, x, z, cmax, y, Problema)
    ###########################################################################

    # Função objetivo:
    jsp_fo_makespan(modelo, x, z, cmax, y, Problema)
    ###########################################################################

    return modelo
Exemplo n.º 2
0
def weigh_data_to_match_preferences(data_pool,
                                    user_preferences,
                                    min_weight=.01):
    # DataFrames zu Vektoren
    input_matrix = to_numpy(data_pool, is_matrix=True)
    target_vector = to_numpy(user_preferences)

    # definiere das Model:
    # finde eine Gewichtung, sodass der Abstand der gewichteten ETFs zu den Präferenzen minimal ist
    # unter der Bedingung, dass die Gewichte null oder zwischen min_weight und eins liegen und zusammen eins ergeben
    model = Model()
    weights = np.array(
        model.semicontinuous_var_list(len(input_matrix), lb=min_weight, ub=1))
    model.minimize(objective_function(weights, input_matrix, target_vector))
    model.add_constraint(sum(weights) == 1)

    # löse das Modell
    result = model.solve()
    return {
        "result": indices_to_tickers(result.as_index_dict(), data_pool),
        "deviance": result.get_objective_value(),
        "status_code": model.solve_details.status_code
    }
def run_GAP_model(As, Bs, Cs, url=None, key=None, **kwargs):
    with Model('GAP per Wolsey -without- Lagrangian Relaxation', **kwargs) as mdl:
        print("#As={}, #Bs={}, #Cs={}".format(len(As), len(Bs), len(Cs)))
        number_of_cs = len(C)
        # variables
        x_vars = [mdl.binary_var_list(c, name=None) for c in Cs]

        # constraints
        mdl.add_constraints(mdl.sum(xv) <= 1 for xv in x_vars)

        mdl.add_constraints(mdl.sum(x_vars[ii][j] * As[ii][j] for ii in range(number_of_cs)) <= bs
                            for j, bs in enumerate(Bs))

        # objective
        total_profit = mdl.sum(mdl.scal_prod(x_i, c_i) for c_i, x_i in zip(Cs, x_vars))
        mdl.maximize(total_profit)
        #  mdl.print_information()
        s = mdl.solve(url=url, key=key)
        assert s is not None
        obj = s.objective_value
        print("* GAP with no relaxation run OK, best objective is: {:g}".format(obj))
    return obj
    def test_qubo_gas_int_paper_example(self):
        """Test the example from https://arxiv.org/abs/1912.04088."""

        # Input.
        model = Model()
        x_0 = model.binary_var(name='x0')
        x_1 = model.binary_var(name='x1')
        x_2 = model.binary_var(name='x2')
        model.minimize(-x_0+2*x_1-3*x_2-2*x_0*x_2-1*x_1*x_2)
        op = QuadraticProgram()
        op.from_docplex(model)

        # Get the optimum key and value.
        n_iter = 10
        gmf = GroverOptimizer(6, num_iterations=n_iter, quantum_instance=self.q_instance)
        results = gmf.solve(op)
        self.validate_results(op, results)
Exemplo n.º 5
0
    def to_quadratic_program(self) -> QuadraticProgram:
        """Convert a number partitioning problem instance into a
        :class:`~qiskit_optimization.problems.QuadraticProgram`

        Returns:
            The :class:`~qiskit_optimization.problems.QuadraticProgram` created
            from the number partitioning problem instance.
        """
        mdl = Model(name="Number partitioning")
        x = {
            i: mdl.binary_var(name=f"x_{i}")
            for i in range(len(self._number_set))
        }
        mdl.add_constraint(
            mdl.sum(num * (-2 * x[i] + 1)
                    for i, num in enumerate(self._number_set)) == 0)
        op = from_docplex_mp(mdl)
        return op
Exemplo n.º 6
0
    def to_quadratic_program(self) -> QuadraticProgram:
        """Convert an SK model problem instance into a
        :class:`~qiskit_optimization.problems.QuadraticProgram`.

        Returns:
            The :class:`~qiskit_optimization.problems.QuadraticProgram` created
            from the SK problem instance.
        """
        mdl = Model(name="SK-model")
        x = mdl.binary_var_list(self._graph.number_of_nodes())

        objective = mdl.sum(
            -1 / np.sqrt(self._num_sites) * self._graph.edges[i, j]["weight"] *
            (2 * x[i] - 1) * (2 * x[j] - 1) for i, j in self._graph.edges)
        # we converted the standard H(x)=-1/\sqrt{n} \sum w_{ij}x_ix_j, where x_i\in\pm 1 to binary.

        mdl.minimize(objective)
        return from_docplex_mp(mdl)
Exemplo n.º 7
0
    def test_qubo_gas_int_paper_example(self, simulator):
        """
        Test the example from https://arxiv.org/abs/1912.04088 using the state vector simulator
        and the qasm simulator
        """

        # Input.
        model = Model()
        x_0 = model.binary_var(name="x0")
        x_1 = model.binary_var(name="x1")
        x_2 = model.binary_var(name="x2")
        model.minimize(-x_0 + 2 * x_1 - 3 * x_2 - 2 * x_0 * x_2 - 1 * x_1 * x_2)
        op = from_docplex_mp(model)

        # Get the optimum key and value.
        q_instance = self.sv_simulator if simulator == "sv" else self.qasm_simulator
        gmf = GroverOptimizer(6, num_iterations=self.n_iter, quantum_instance=q_instance)
        results = gmf.solve(op)
        self.validate_results(op, results)
Exemplo n.º 8
0
    def to_quadratic_program(self) -> QuadraticProgram:
        """Convert a Max-cut problem instance into a
        :class:`~qiskit_optimization.problems.QuadraticProgram`

        Returns:
            The :class:`~qiskit_optimization.problems.QuadraticProgram` created
            from the Max-cut problem instance.
        """
        mdl = Model(name='Max-cut')
        x = {i: mdl.binary_var(name='x_{0}'.format(i))
             for i in range(self._graph.number_of_nodes())}
        for w, v in self._graph.edges:
            self._graph.edges[w, v].setdefault('weight', 1)
        objective = mdl.sum(self._graph.edges[i, j]['weight'] * x[i]
                            * (1 - x[j]) + self._graph.edges[i, j]['weight'] * x[j]
                            * (1 - x[i]) for i, j in self._graph.edges)
        mdl.maximize(objective)
        op = QuadraticProgram()
        op.from_docplex(mdl)
        return op
 def test_continuous_variable_decode(self):
     """Test decode func of IntegerToBinaryConverter for continuous variables"""
     mdl = Model("test_continuous_varable_decode")
     c = mdl.continuous_var(lb=0, ub=10.9, name="c")
     x = mdl.binary_var(name="x")
     mdl.maximize(c + x * x)
     op = from_docplex_mp(mdl)
     converter = IntegerToBinary()
     op = converter.convert(op)
     admm_params = ADMMParameters()
     qubo_optimizer = MinimumEigenOptimizer(NumPyMinimumEigensolver())
     continuous_optimizer = CplexOptimizer()
     solver = ADMMOptimizer(
         qubo_optimizer=qubo_optimizer,
         continuous_optimizer=continuous_optimizer,
         params=admm_params,
     )
     result = solver.solve(op)
     new_x = converter.interpret(result.x)
     self.assertEqual(new_x[0], 10.9)
Exemplo n.º 10
0
    def test_docplex_constant_and_quadratic_terms_in_object_function(self):
        # Create an Ising Homiltonian with docplex
        laplacian = np.array([[-3., 1., 1., 1.], [1., -2., 1., -0.],
                              [1., 1., -3., 1.], [1., -0., 1., -2.]])

        mdl = Model()
        n = laplacian.shape[0]
        bias = [0] * 4
        x = {i: mdl.binary_var(name='x_{0}'.format(i)) for i in range(n)}
        couplers_func = mdl.sum(2 * laplacian[i, j] * (2 * x[i] - 1) *
                                (2 * x[j] - 1) for i in range(n - 1)
                                for j in range(i, n))
        bias_func = mdl.sum(float(bias[i]) * x[i] for i in range(n))
        ising_func = couplers_func + bias_func
        mdl.minimize(ising_func)
        qubitOp, offset = docplex.get_qubitops(mdl)

        ee = ExactEigensolver(qubitOp, k=1)
        result = ee.run()

        expected_result = -22

        # Compare objective
        self.assertEqual(result['energy'] + offset, expected_result)
Exemplo n.º 11
0
    def test_integer_variables(self):
        """Tests ADMM with integer variables."""
        mdl = Model("integer-variables")

        v = mdl.integer_var(lb=5, ub=20, name="v")
        w = mdl.continuous_var(name="w", lb=0.0)

        mdl.minimize(v + w)
        op = from_docplex_mp(mdl)

        solver = ADMMOptimizer()
        solution = solver.solve(op)

        self.assertIsNotNone(solution)
        self.assertIsInstance(solution, ADMMOptimizationResult)
        self.assertIsNotNone(solution.x)
        np.testing.assert_almost_equal([5.0, 0.0], solution.x, 3)
        self.assertIsNotNone(solution.fval)
        np.testing.assert_almost_equal(5.0, solution.fval, 3)
        self.assertIsNotNone(solution.state)
        self.assertIsInstance(solution.state, ADMMState)
Exemplo n.º 12
0
    def test_integer_variables(self):
        """Tests ADMM with integer variables."""
        mdl = Model('integer-variables')

        v = mdl.integer_var(lb=5, ub=20, name='v')
        w = mdl.continuous_var(name='w', lb=0.)

        mdl.minimize(v + w)
        op = QuadraticProgram()
        op.from_docplex(mdl)

        solver = ADMMOptimizer()
        solution = solver.solve(op)

        self.assertIsNotNone(solution)
        self.assertIsInstance(solution, ADMMOptimizationResult)
        self.assertIsNotNone(solution.x)
        np.testing.assert_almost_equal([5., 0.], solution.x, 3)
        self.assertIsNotNone(solution.fval)
        np.testing.assert_almost_equal(5., solution.fval, 3)
        self.assertIsNotNone(solution.state)
        self.assertIsInstance(solution.state, ADMMState)
Exemplo n.º 13
0
    def test_admm_maximization(self):
        """Tests a simple maximization problem using ADMM optimizer"""
        mdl = Model('simple-max')
        c = mdl.continuous_var(lb=0, ub=10, name='c')
        x = mdl.binary_var(name='x')
        mdl.maximize(c + x * x)
        op = QuadraticProgram()
        op.from_docplex(mdl)

        admm_params = ADMMParameters()

        solver = ADMMOptimizer(params=admm_params,
                               continuous_optimizer=CobylaOptimizer())
        solution = solver.solve(op)
        self.assertIsNotNone(solution)
        self.assertIsInstance(solution, ADMMOptimizationResult)

        self.assertIsNotNone(solution.x)
        np.testing.assert_almost_equal([10, 0], solution.x, 3)
        self.assertIsNotNone(solution.fval)
        np.testing.assert_almost_equal(10, solution.fval, 3)
        self.assertIsNotNone(solution.state)
        self.assertIsInstance(solution.state, ADMMState)
Exemplo n.º 14
0
def max_cut_qp(adjacency_matrix: np.ndarray) -> QuadraticProgram:
    """
    Creates the max-cut instance based on the adjacency graph.
    """

    size = len(adjacency_matrix)

    mdl = Model()
    x = [mdl.binary_var('x%s' % i) for i in range(size)]

    objective_terms = []
    for i in range(size):
        for j in range(size):
            if adjacency_matrix[i, j] != 0.:
                objective_terms.append(
                    adjacency_matrix[i, j] * x[i] * (1 - x[j]))

    objective = mdl.sum(objective_terms)
    mdl.maximize(objective)

    q_p = QuadraticProgram()
    q_p.from_docplex(mdl)

    return q_p
Exemplo n.º 15
0
 def test_continuous_variable_decode(self):
     """ Test decode func of IntegerToBinaryConverter for continuous variables"""
     try:
         mdl = Model('test_continuous_varable_decode')
         c = mdl.continuous_var(lb=0, ub=10.9, name='c')
         x = mdl.binary_var(name='x')
         mdl.maximize(c + x * x)
         op = QuadraticProgram()
         op.from_docplex(mdl)
         converter = IntegerToBinary()
         op = converter.convert(op)
         admm_params = ADMMParameters()
         qubo_optimizer = MinimumEigenOptimizer(NumPyMinimumEigensolver())
         continuous_optimizer = CplexOptimizer()
         solver = ADMMOptimizer(
             qubo_optimizer=qubo_optimizer,
             continuous_optimizer=continuous_optimizer,
             params=admm_params,
         )
         result = solver.solve(op)
         new_x = converter.interpret(result.x)
         self.assertEqual(new_x[0], 10.9)
     except MissingOptionalLibraryError as ex:
         self.skipTest(str(ex))
Exemplo n.º 16
0
def make_cutstock_pattern_generation_model(items, roll_width, **kwargs):
    gen_model = Model(name='cutstock_generate_patterns', **kwargs)
    # store data
    gen_model.items = items
    gen_model.roll_width = roll_width
    # default values
    gen_model.duals = [1] * len(items)
    # 1. create variables: one per item
    gen_model.use_vars = gen_model.integer_var_list(keys=items,
                                                    ub=999999,
                                                    name='use')
    # 2 setup constraint:
    # --- sum of item usage times item sizes must be less than roll width
    gen_model.add(
        gen_model.dot(gen_model.use_vars, (it.size
                                           for it in items)) <= roll_width)

    # store dual expression for dynamic edition
    gen_model.use_dual_expr = 1 - gen_model.dot(gen_model.use_vars,
                                                gen_model.duals)
    # minimize
    gen_model.minimize(gen_model.use_dual_expr)

    return gen_model
Exemplo n.º 17
0
def no_linearization(quad, **kwargs):
	"""
	Solve a problem using the solver's default approach to quadratics (for cplex, this is the std linearization)
	"""
	n = quad.n
	c = quad.c
	m = Model(name='no_linearization')
	x = m.binary_var_list(n, name="binary_var")
	if type(quad) is Knapsack: #HSP and UQP don't have cap constraint
		#add capacity constraint(s)
		for k in range(quad.m):
			m.add_constraint(m.sum(x[i]*quad.a[k][i] for i in range(n)) <= quad.b[k])

	#k_item constraint if necessary (if KQKP or HSP)
	if quad.num_items > 0:
		m.add_constraint(m.sum(x[i] for i in range(n)) == quad.num_items)

	#compute quadratic values contirbution to obj
	quadratic_values = 0
	for i in range(n):
		for j in range(i+1,n):
			quadratic_values = quadratic_values + (x[i]*x[j]*quad.C[i,j])
	#set objective function
	linear_values = m.sum(x[i]*c[i] for i in range(n))
	m.maximize(linear_values + quadratic_values)

	return [m, 0]
Exemplo n.º 18
0
def qsap_ss(qsap, **kwargs):
	"""
	Sherali-Smith Linear Formulation for the quadratic semi-assignment problem
	"""
	n = qsap.n
	m = qsap.m
	e = qsap.e
	c = qsap.c

	#create model and add variables
	mdl = Model(name='qsap_ss')
	x = mdl.binary_var_matrix(m,n,name="binary_var")
	s = mdl.continuous_var_matrix(m,n)
	y = mdl.continuous_var_matrix(m,n)

	mdl.add_constraints((sum(x[i,k] for k in range(n)) == 1) for i in range(m))

	start = timer()
	U = np.zeros((m,n))
	L = np.zeros((m,n))
	bound_mdl = Model(name='upper_bound_model')
	bound_x = bound_mdl.continuous_var_matrix(keys1=m,keys2=n,ub=1,lb=0)
	bound_mdl.add_constraints((sum(bound_x[i,k] for k in range(n)) == 1) for i in range(m))
	for i in range(m-1):
		for k in range(n):
			# solve for upper bound
			bound_mdl.set_objective(sense="max", expr=sum(sum(c[i,k,j,l]*bound_x[j,l] for l in range(n)) for j in range(i+1,m)))
			bound_mdl.solve()
			U[i,k] = bound_mdl.objective_value

			# solve for lower bound
			bound_mdl.set_objective(sense="min", expr=sum(sum(c[i,k,j,l]*bound_x[j,l] for l in range(n)) for j in range(i+1,m)))
			bound_mdl.solve()
			L[i,k] = bound_mdl.objective_value
	# end bound model
	bound_mdl.end()
	end = timer()
	setup_time = end-start
	#add auxiliary constraints
	for i in range(m-1):
		for k in range(n):
			mdl.add_constraint(sum(sum(c[i,k,j,l]*x[j,l] for j in range(i+1,m)) for l in range(n))-s[i,k]-L[i,k]==y[i,k])
			mdl.add_constraint(y[i,k] <= (U[i,k]-L[i,k])*(1-x[i,k]))
			mdl.add_constraint(s[i,k] <= (U[i,k]-L[i,k])*x[i,k])

	#set objective function
	linear_values = sum(sum(e[i,k]*x[i,k] for i in range(m)) for k in range(n))
	mdl.maximize(linear_values + sum(sum(s[i,k]+(x[i,k]*L[i,k]) for i in range(m-1)) for k in range(n)))

	#return model + setup time
	return [mdl, setup_time]
Exemplo n.º 19
0
def qsap_elf(qsap, **kwargs):
	"""
	extended linear formulation for the quadratic semi-assignment problem
	"""
	n = qsap.n
	m = qsap.m
	e = qsap.e
	c = qsap.c
	mdl = Model(name='qsap_elf')
	x = mdl.binary_var_matrix(m,n,name="binary_var")
	z = np.array([[[[[[mdl.continuous_var() for i in range(n)]for j in range(m)]
						for k in range(n)]for l in range(m)] for s in range(n)] for t in range(m)])
	mdl.add_constraints((sum(x[i,k] for k in range(n)) == 1) for i in range(m))

	#add auxiliary constraints
	for i in range(m-1):
		for j in range(i+1,m):
			for k in range(n):
				for l in range(n):
					mdl.add_constraint(z[i,k,i,k,j,l] + z[j,l,i,k,j,l] <= 1)
					mdl.add_constraint(x[i,k] + z[i,k,i,k,j,l] <= 1)
					mdl.add_constraint(x[j,l] + z[j,l,i,k,j,l] <= 1)
					mdl.add_constraint(x[i,k] + z[i,k,i,k,j,l] + z[j,l,i,k,j,l] >= 1)
					mdl.add_constraint(x[j,l] + z[i,k,i,k,j,l] + z[j,l,i,k,j,l] >= 1)

	#compute quadratic values contirbution to obj
	constant = 0
	quadratic_values = 0
	for i in range(m-1):
		for j in range(i+1,m):
			for k in range(n):
				for l in range(n):
					constant = constant + c[i,k,j,l]
					quadratic_values = quadratic_values + (c[i,k,j,l]*(z[i,k,i,k,j,l]+z[j,l,i,k,j,l]))

	linear_values = mdl.sum(x[i,k]*e[i,k] for k in range(n) for i in range(m))
	mdl.maximize(linear_values + constant - quadratic_values)

	#return model + setup time=0
	return [mdl, 0]
def build_sports(context=None):
    print("* building sport scheduling model instance")
    mdl = Model('sportSchedCPLEX', context=context)

    nb_teams_in_division, nb_intra_divisional, nb_inter_divisional = nbs
    assert len(team_div1) == len(team_div2)
    mdl.teams = list(team_div1 | team_div2)
    # team index ranges from 1 to 2N
    team_range = range(1, 2 * nb_teams_in_division + 1)

    # Calculate the number of weeks necessary.
    nb_weeks = (nb_teams_in_division - 1) * nb_intra_divisional + nb_teams_in_division * nb_inter_divisional
    weeks = range(1, nb_weeks + 1)
    mdl.weeks = weeks

    print("{0} games, {1} intradivisional, {2} interdivisional"
          .format(nb_weeks, (nb_teams_in_division - 1) * nb_intra_divisional,
                  nb_teams_in_division * nb_inter_divisional))

    # Season is split into two halves.
    first_half_weeks = range(1, nb_weeks // 2 + 1)
    nb_first_half_games = nb_weeks // 3

    # All possible matches (pairings) and whether of not each is intradivisional.
    matches = [Match(t1, t2, 1 if (t2 <= nb_teams_in_division or t1 > nb_teams_in_division) else 0)
               for t1 in team_range for t2 in team_range if t1 < t2]
    mdl.matches = matches
    # Number of games to play between pairs depends on
    # whether the pairing is intradivisional or not.
    nb_play = {m: nb_intra_divisional if m.is_divisional == 1 else nb_inter_divisional for m in matches}

    plays = mdl.binary_var_matrix(keys1=matches, keys2=weeks,
                                    name=lambda mw: "play_%d_%d_w%d" % (mw[0].team1, mw[0].team2, mw[1]))
    mdl.plays = plays

    for m in matches:
        mdl.add_constraint(mdl.sum(plays[m, w] for w in weeks) == nb_play[m],
                             "correct_nb_games_%d_%d" % (m.team1, m.team2))

    for w in weeks:
        # Each team must play exactly once in a week.
        for t in team_range:
            max_teams_in_division = (plays[m, w] for m in matches if m.team1 == t or m.team2 == t)
            mdl.add_constraint(mdl.sum(max_teams_in_division) == 1,
                                 "plays_exactly_once_%d_%s" % (w, t))

        # Games between the same teams cannot be on successive weeks.
        for m in matches:
            if w < nb_weeks:
                mdl.add_constraint(plays[m, w] + plays[m, w + 1] <= 1)

    # Some intradivisional games should be in the first half.
    for t in team_range:
        max_teams_in_division = [plays[m, w] for w in first_half_weeks for m in matches if
                                 m.is_divisional == 1 and (m.team1 == t or m.team2 == t)]

        mdl.add_constraint(mdl.sum(max_teams_in_division) >= nb_first_half_games,
                             "in_division_first_half_%s" % t)

    # postpone divisional matches as much as possible
    # we weight each play variable with the square of w.
    mdl.maximize(mdl.sum(plays[m, w] * w * w for w in weeks for m in matches if m.is_divisional))
    return mdl
Exemplo n.º 21
0
def solve(dat, out, err, progress):
    assert isinstance(progress, Progress)
    assert isinstance(out, LogFile) and isinstance(err, LogFile)
    assert dataFactory.good_tic_dat_object(dat)
    assert not dataFactory.find_foreign_key_failures(dat)
    assert not dataFactory.find_data_type_failures(dat)
    out.write("COG output log\n%s\n\n" % time_stamp())
    err.write("COG error log\n%s\n\n" % time_stamp())

    def get_distance(x, y):
        if (x, y) in dat.distance:
            return dat.distance[x, y]["distance"]
        if (y, x) in dat.distance:
            return dat.distance[y, x]["distance"]
        return float("inf")

    def can_assign(x, y):
        return dat.sites[y]["center_status"] == "Can Be Center" \
               and get_distance(x,y)<float("inf")

    unassignables = [
        n for n in dat.sites
        if not any(can_assign(n, y)
                   for y in dat.sites) and dat.sites[n]["demand"] > 0
    ]
    if unassignables:
        # Infeasibility detected. Generate an error table and return None
        err.write("The following sites have demand, but can't be " +
                  "assigned to anything.\n")
        err.log_table("Un-assignable Demand Points",
                      [["Site"]] + [[_] for _ in unassignables])
        return

    useless = [
        n for n in dat.sites
        if not any(can_assign(y, n)
                   for y in dat.sites) and dat.sites[n]["demand"] == 0
    ]
    if useless:
        # Log in the error table as a warning, but can still try optimization.
        err.write(
            "The following sites have no demand, and can't serve as the " +
            "center point for any assignments.\n")
        err.log_table("Useless Sites", [["Site"]] + [[_] for _ in useless])

    progress.numerical_progress("Feasibility Analysis", 100)

    m = Model("cog")

    assign_vars = {(n, assigned_to):
                   m.binary_var(name="%s_%s" % (n, assigned_to))
                   for n in dat.sites for assigned_to in dat.sites
                   if can_assign(n, assigned_to)}
    open_vars = {
        n: m.binary_var(name="open_%s" % n)
        for n in dat.sites if dat.sites[n]["center_status"] == "Can Be Center"
    }
    if not open_vars:
        err.write("Nothing can be a center!\n")  # Infeasibility detected.
        return

    progress.numerical_progress("Core Model Creation", 50)

    assign_slicer = Slicer(assign_vars)

    for n, r in dat.sites.items():
        if r["demand"] > 0:
            m.add_constraint(m.sum(
                assign_vars[n, assign_to]
                for _, assign_to in assign_slicer.slice(n, "*")) == 1,
                             ctname="must_assign_%s" % n)

    crippledfordemo = "formulation" in dat.parameters and \
                      dat.parameters["formulation"]["value"] == "weak"
    for assigned_to, r in dat.sites.items():
        if r["center_status"] == "Can Be Center":
            _assign_vars = [
                assign_vars[n, assigned_to]
                for n, _ in assign_slicer.slice("*", assigned_to)
            ]
            if crippledfordemo:
                m.add_constraint(m.sum(_assign_vars) <=
                                 len(_assign_vars) * open_vars[assigned_to],
                                 ctname="weak_force_open%s" % assigned_to)
            else:
                for var in _assign_vars:
                    m.add_constraint(var <= open_vars[assigned_to],
                                     ctname="strong_force_open_%s" %
                                     assigned_to)

    number_of_centroids = dat.parameters["Number of Centroids"]["value"] \
                          if "Number of Centroids" in dat.parameters else 1
    if number_of_centroids <= 0:
        err.write("Need to specify a positive number of centroids\n"
                  )  # Infeasibility detected.
        return

    m.add_constraint(m.sum(v
                           for v in open_vars.values()) == number_of_centroids,
                     ctname="numCentroids")

    if "mipGap" in dat.parameters:
        m.parameters.mip.tolerances.mipgap = dat.parameters["mipGap"]["value"]

    progress.numerical_progress("Core Model Creation", 100)

    m.minimize(
        m.sum(var * get_distance(n, assigned_to) * dat.sites[n]["demand"]
              for (n, assigned_to), var in assign_vars.items()))

    progress.add_cplex_listener("COG Optimization", m)

    if m.solve():

        progress.numerical_progress("Core Optimization", 100)
        cplex_soln = m.solution
        sln = solutionFactory.TicDat()
        # see code trick http://ibm.co/2aQwKYG
        if m.solve_details.status == 'optimal':
            sln.parameters["Lower Bound"] = cplex_soln.get_objective_value()
        else:
            sln.parameters["Lower Bound"] = m.solve_details.get_best_bound()
        sln.parameters["Upper Bound"] = cplex_soln.get_objective_value()
        out.write('Upper Bound: %g\n' % sln.parameters["Upper Bound"]["value"])
        out.write('Lower Bound: %g\n' % sln.parameters["Lower Bound"]["value"])

        def almostone(x):
            return abs(x - 1) < 0.0001

        for (n, assigned_to), var in assign_vars.items():
            if almostone(cplex_soln.get_value(var)):
                sln.assignments[n, assigned_to] = {}
        for n, var in open_vars.items():
            if almostone(cplex_soln.get_value(var)):
                sln.openings[n] = {}
        out.write('Number Centroids: %s\n' % len(sln.openings))
        progress.numerical_progress("Full Cog Solve", 100)
        return sln
Exemplo n.º 22
0
    def test_admm_ex6_max(self):
        """Example 6 as maximization"""
        try:
            mdl = Model('ex6-max')

            # pylint:disable=invalid-name
            v = mdl.binary_var(name='v')
            w = mdl.binary_var(name='w')
            t = mdl.binary_var(name='t')
            u = mdl.continuous_var(name='u')

            # mdl.minimize(v + w + t + 5 * (u - 2) ** 2)
            mdl.maximize(-v - w - t - 5 * (u - 2)**2)
            mdl.add_constraint(v + 2 * w + t + u <= 3, "cons1")
            mdl.add_constraint(v + w + t >= 1, "cons2")
            mdl.add_constraint(v + w == 1, "cons3")

            op = QuadraticProgram()
            op.from_docplex(mdl)

            qubo_optimizer = CplexOptimizer()
            continuous_optimizer = CplexOptimizer()

            admm_params = ADMMParameters(rho_initial=1001,
                                         beta=1000,
                                         factor_c=900,
                                         max_iter=100,
                                         three_block=True,
                                         tol=1.e-6)

            solver = ADMMOptimizer(params=admm_params,
                                   qubo_optimizer=qubo_optimizer,
                                   continuous_optimizer=continuous_optimizer)
            solution = solver.solve(op)

            self.assertIsNotNone(solution)
            self.assertIsInstance(solution, ADMMOptimizationResult)
            self.assertIsNotNone(solution.x)
            np.testing.assert_almost_equal([1., 0., 0., 2.], solution.x, 3)
            self.assertIsNotNone(solution.fval)
            np.testing.assert_almost_equal(-1., solution.fval, 3)
            self.assertIsNotNone(solution.state)
            self.assertIsInstance(solution.state, ADMMState)
        except NameError as ex:
            self.skipTest(str(ex))
Exemplo n.º 23
0
def make_custstock_master_model(item_table, pattern_table, fill_table,
                                roll_width, **kwargs):
    m = Model(name='custock_master', **kwargs)

    # store data as properties
    m.items = [TItem.make(it_row) for it_row in item_table]
    m.items_by_id = {it.id: it for it in m.items}
    m.patterns = [TPattern(*pattern_row) for pattern_row in pattern_table]
    m.patterns_by_id = {pat.id: pat for pat in m.patterns}
    m.max_pattern_id = max(pt.id for pt in m.patterns)

    # build a dictionary storing how much each pattern fills each item.
    m.pattern_item_filled = {(m.patterns_by_id[p], m.items_by_id[i]): f
                             for (p, i, f) in fill_table}
    m.roll_width = roll_width

    # --- variables
    # one cut var per pattern...
    m.MAX_CUT = 9999
    m.cut_vars = m.continuous_var_dict(m.patterns,
                                       lb=0,
                                       ub=m.MAX_CUT,
                                       name='cut')

    # --- add fill constraints
    #
    all_patterns = m.patterns
    all_items = m.items
    m.item_fill_cts = []
    for item in all_items:
        item_fill_ct = m.sum(
            m.cut_vars[p] * m.pattern_item_filled.get((p, item), 0)
            for p in all_patterns) >= item.demand
        item_fill_ct.name = 'ct_fill_{0!s}'.format(item)
        m.item_fill_cts.append(item_fill_ct)
    m.add_constraints(m.item_fill_cts)

    # --- minimize total cut stock
    m.total_cutting_cost = m.sum(m.cut_vars[p] * p.cost for p in all_patterns)
    m.minimize(m.total_cutting_cost)

    return m
Exemplo n.º 24
0
def build_production_problem(products, resources, consumptions, context=None):
    """ Takes as input:
        - a list of product tuples (name, demand, inside, outside)
        - a list of resource tuples (name, capacity)
        - a list of consumption tuples (product_name, resource_named, consumed)
    """
    mdl = Model('production', context=context)
    # --- decision variables ---
    mdl.inside_vars = mdl.continuous_var_dict(products, name='inside')
    mdl.outside_vars = mdl.continuous_var_dict(products, name='outside')

    # --- constraints ---
    # demand satisfaction
    for prod in products:
        mdl.add_constraint(mdl.inside_vars[prod] + mdl.outside_vars[prod] >= prod[1])

    # --- resource capacity ---
    for res in resources:
        mdl.add_constraint(mdl.sum([mdl.inside_vars[p] * consumptions[p[0], res[0]] for p in products]) <= res[1])

    # --- objective ---
    mdl.total_inside_cost = mdl.sum(mdl.inside_vars[p] * p[2] for p in products)
    mdl.total_outside_cost = mdl.sum(mdl.outside_vars[p] * p[3] for p in products)
    mdl.minimize(mdl.total_inside_cost + mdl.total_outside_cost)
    return mdl
def run_GAP_model(As, Bs, Cs, context=None, **kwargs):
    mdl = Model('GAP per Wolsey -without- Lagrangian Relaxation', context=context)
    print("#As={}, #Bs={}, #Cs={}".format(len(As), len(Bs), len(Cs)))
    number_of_cs = len(C)
    # variables
    x_vars = [mdl.binary_var_list(c, name=None) for c in Cs]

    # constraints

    for xv in x_vars:
        mdl.add_constraint(mdl.sum(xv) <= 1)

    for j, bs in enumerate(Bs):
        mdl.add_constraint(mdl.sum(x_vars[ii][j] * As[ii][j] for ii in range(number_of_cs)) <= bs)

    # objective
    total_profit = mdl.sum(mdl.sum(c_ij * x_ij for c_ij, x_ij in zip(c_i, x_i))
                           for c_i, x_i in zip(Cs, x_vars))
    mdl.maximize(total_profit)
    mdl.print_information()
    assert mdl.solve(**kwargs)
    obj = mdl.objective_value
    mdl.print_information()
    print("* GAP with no relaxation run OK, best objective is: {:g}".format(obj))
    mdl.end()
    return obj
Exemplo n.º 26
0
def build_diet_model(**kwargs):
    # Create tuples with named fields for foods and nutrients
    Food = namedtuple("Food", ["name", "unit_cost", "qmin", "qmax"])
    food = [Food(*f) for f in FOODS]

    Nutrient = namedtuple("Nutrient", ["name", "qmin", "qmax"])
    nutrients = [Nutrient(*row) for row in NUTRIENTS]

    food_nutrients = {(fn[0], nutrients[n].name):
                      fn[1 + n] for fn in FOOD_NUTRIENTS for n in range(len(NUTRIENTS))}

    # Model
    mdl = Model("diet", **kwargs)

    # Decision variables, limited to be >= Food.qmin and <= Food.qmax
    qty = dict((f, mdl.continuous_var(f.qmin, f.qmax, f.name)) for f in food)

    # Limit range of nutrients, and mark them as KPIs
    for n in nutrients:
        amount = mdl.sum(qty[f] * food_nutrients[f.name, n.name] for f in food)
        mdl.add_range(n.qmin, amount, n.qmax)
        mdl.add_kpi(amount, publish_name="Total %s" % n.name)

    # Minimize cost
    mdl.minimize(mdl.sum(qty[f] * f.unit_cost for f in food))

    mdl.print_information()
    return mdl
def run_GAP_model_with_Lagrangian_relaxation(As, Bs, Cs, max_iters=101, context=None, **kwargs):
    mdl = Model('GAP per Wolsey -with- Lagrangian Relaxation', context=context)
    print("#As={}, #Bs={}, #Cs={}".format(len(As), len(Bs), len(Cs)))
    c_range = range(len(Cs))
    # variables
    x_vars = [mdl.binary_var_list(c, name=None) for c in Cs]
    p_vars = [mdl.continuous_var(lb=0) for _ in Cs]  # new for relaxation

    for (xv, pv) in izip(x_vars, p_vars):
        # was  mdl.add_constraint(mdl.sum(xVars[i]) <= 1)
        mdl.add_constraint(mdl.sum(xv) == 1 - pv)

    for j, bs in enumerate(Bs):
        mdl.add_constraint(mdl.sum(x_vars[ii][j] * As[ii][j] for ii in c_range) <= bs)

    # lagrangian relaxation loop
    eps = 1e-6
    loop_count = 0
    best = 0
    initial_multiplier = 1
    multipliers = [initial_multiplier] * len(Cs)

    total_profit = mdl.sum(mdl.sum(c_ij * x_ij for c_ij, x_ij in zip(c_i, x_i)) for c_i, x_i in zip(Cs, x_vars))
    mdl.add_kpi(total_profit, "Total profit")

    while loop_count <= max_iters:
        loop_count += 1
        # rebuilt at each loop iteration
        total_penalty = mdl.sum(p_vars[i] * multipliers[i] for i in c_range)
        mdl.maximize(total_profit + total_penalty)
        ok = mdl.solve(**kwargs)
        if not ok:
            print("*** solve fails, stopping at iteration: %d" % loop_count)
            break
        best = mdl.objective_value
        penalties = [pv.solution_value for pv in p_vars]
        print('%d> new lagrangian iteration, obj=%g, m=%s, p=%s' % (loop_count, best, str(multipliers), str(penalties)))

        do_stop = True
        justifier = 0
        for k in c_range:
            penalized_violation = penalties[k] * multipliers[k]
            if penalized_violation >= eps:
                do_stop = False
                justifier = penalized_violation
                break

        if do_stop:
            print("* Lagrangian relaxation succeeds, best={:g}, penalty={:g}, #iterations={}"
                  .format(best, total_penalty.solution_value, loop_count))
            break
        else:
            # update multipliers and start loop again.
            scale_factor = 1.0 / float(loop_count)
            multipliers = [max(multipliers[i] - scale_factor * penalties[i], 0.) for i in c_range]
            print('{}> -- loop continues, m={}, justifier={:g}'.format(loop_count, str(multipliers), justifier))

    return best
Exemplo n.º 28
0
    def test_admm_ex6(self):
        """Example 6 as a unit test. Example 6 is reported in:
        Gambella, C., & Simonetto, A. (2020).
        Multi-block ADMM Heuristics for Mixed-Binary Optimization on Classical
        and Quantum Computers.
        arXiv preprint arXiv:2001.02069."""
        try:
            mdl = Model('ex6')

            # pylint:disable=invalid-name
            v = mdl.binary_var(name='v')
            w = mdl.binary_var(name='w')
            t = mdl.binary_var(name='t')
            u = mdl.continuous_var(name='u')

            mdl.minimize(v + w + t + 5 * (u - 2)**2)
            mdl.add_constraint(v + 2 * w + t + u <= 3, "cons1")
            mdl.add_constraint(v + w + t >= 1, "cons2")
            mdl.add_constraint(v + w == 1, "cons3")

            op = QuadraticProgram()
            op.from_docplex(mdl)

            qubo_optimizer = CplexOptimizer()
            continuous_optimizer = CplexOptimizer()

            admm_params = ADMMParameters(rho_initial=1001,
                                         beta=1000,
                                         factor_c=900,
                                         max_iter=100,
                                         three_block=True,
                                         tol=1.e-6)

            solver = ADMMOptimizer(params=admm_params,
                                   qubo_optimizer=qubo_optimizer,
                                   continuous_optimizer=continuous_optimizer)
            solution = solver.solve(op)

            self.assertIsNotNone(solution)
            self.assertIsInstance(solution, ADMMOptimizationResult)
            self.assertIsNotNone(solution.x)
            np.testing.assert_almost_equal([1., 0., 0., 2.], solution.x, 3)
            self.assertIsNotNone(solution.fval)
            np.testing.assert_almost_equal(1., solution.fval, 3)
            self.assertIsNotNone(solution.state)
            self.assertIsInstance(solution.state, ADMMState)
        except NameError as ex:
            self.skipTest(str(ex))
Exemplo n.º 29
0
def glovers_linearization(quad, bounds="tight", constraints="original", lhs_constraints=False, use_diagonal=False, **kwargs):
	"""
	Apply glovers linearization to a QP and return resulting model
	"""
	n = quad.n
	c = quad.c
	C = quad.C
	a = quad.a
	b = quad.b

	#put linear terms along diagonal of quadratic matrix. set linear terms to zero
	if use_diagonal:
		for i in range(n):
			C[i,i] = c[i]
			c[i] = 0

	#create model and add variables
	m = Model(name='glovers_linearization_'+bounds+'_'+constraints)
	x = m.binary_var_list(n, name="binary_var")

	if type(quad) is Knapsack: #HSP and UQP don't have cap constraint
		#add capacity constraint(s)
		for k in range(quad.m):
			m.add_constraint(m.sum(x[i]*a[k][i] for i in range(n)) <= b[k])

	#k_item constraint if necessary (if KQKP or HSP)
	if quad.num_items > 0:
		m.add_constraint(m.sum(x[i] for i in range(n)) == quad.num_items)

	#determine bounds for each column of C
	#U1,L1 must take item at index j, U0,L0 must not take
	U1 = np.zeros(n)
	L0 = np.zeros(n)
	U0 = np.zeros(n)
	L1 = np.zeros(n)
	start = timer()
	if(bounds=="original" or type(quad)==UQP):
		for j in range(n):
			col = C[:, j]
			pos_take_vals = col > 0
			pos_take_vals[j] = True
			U1[j] = np.sum(col[pos_take_vals])
			neg_take_vals = col < 0
			neg_take_vals[j] = False
			L0[j] = np.sum(col[neg_take_vals])
			if lhs_constraints:
				U0[j] = U1[j] - col[j]
				L1[j] = L0[j] + col[j]
	elif(bounds=="tight" or bounds=="tighter"):
		bound_m = Model(name='bound_model')
		if bounds == "tight":
			#for tight bounds solve for upper bound of col w/ continuous vars
			bound_x = bound_m.continuous_var_list(n, ub=1, lb=0)
		elif bounds == "tighter":
			#for even tighter bounds, instead use binary vars
			bound_x = bound_m.binary_var_list(n, ub=1, lb=0)
		if type(quad) is Knapsack:
			for k in range(quad.m):
				#add capacity constraints
				bound_m.add_constraint(bound_m.sum(bound_x[i]*a[k][i] for i in range(n)) <= b[k])
		if quad.num_items > 0:
			bound_m.add_constraint(bound_m.sum(bound_x[i] for i in range(n)) == quad.num_items)
		for j in range(n):
			# solve for upper bound U1
			bound_m.set_objective(sense="max", expr=bound_m.sum(C[i,j]*bound_x[i] for i in range(n)))
			u_con = bound_m.add_constraint(bound_x[j]==1)
			bound_m.solve()
			if "OPTIMAL_SOLUTION" not in str(bound_m.get_solve_status()):
				bound_m.remove_constraint(u_con)
				bound_m.add_constraint(bound_x[j]==0)
				m.add_constraint(x[j]==0)
				bound_m.solve()
			else:
				bound_m.remove_constraint(u_con)
			U1[j] = bound_m.objective_value

			# solve for lower bound L0
			bound_m.set_objective(sense="min", expr=bound_m.sum(C[i,j]*bound_x[i] for i in range(n)))
			l_con = bound_m.add_constraint(bound_x[j]==0)
			bound_m.solve()
			if "OPTIMAL_SOLUTION" not in str(bound_m.get_solve_status()):
				bound_m.remove_constraint(l_con)
				bound_m.add_constraint(bound_x[j]==1)
				m.add_constraint(x[j]==1)
				bound_m.solve()
			else:
				bound_m.remove_constraint(l_con)
			L0[j] = bound_m.objective_value

			if lhs_constraints:
				# solve for upper bound U0
				bound_m.set_objective(sense="max", expr=bound_m.sum(C[i,j]*bound_x[i] for i in range(n)))
				u_con = bound_m.add_constraint(bound_x[j] == 0)
				bound_m.solve()
				if "OPTIMAL_SOLUTION" not in str(bound_m.get_solve_status()):
					bound_m.remove_constraint(u_con)
					bound_m.add_constraint(bound_x[j]==1)
					m.add_constraint(x[j]==1)
					bound_m.solve()
				else:
					bound_m.remove_constraint(u_con)
				U0[j] = bound_m.objective_value

				# solve for lower bound L1
				bound_m.set_objective(sense="min", expr=bound_m.sum(C[i,j]*bound_x[i] for i in range(n)))
				l_con = bound_m.add_constraint(bound_x[j] == 1)
				bound_m.solve()
				if "OPTIMAL_SOLUTION" not in str(bound_m.get_solve_status()):
					bound_m.remove_constraint(l_con)
					bound_m.add_constraint(bound_x[j]==0)
					m.add_constraint(x[j]==0)
					bound_m.solve()
				else:
					bound_m.remove_constraint(l_con)
				L1[j] = bound_m.objective_value
		#end bound model
		bound_m.end()
	else:
		raise Exception(bounds + " is not a valid bound type for glovers")
	end = timer()
	setup_time = end-start



	#add auxiliary constrains
	if(constraints=="original"):
		#original glovers constraints
		z = m.continuous_var_list(keys=n,lb=-m.infinity)
		m.add_constraints(z[j] <= U1[j]*x[j] for j in range(n))
		if lhs_constraints:
			m.add_constraints(z[j] >= L1[j]*x[j] for j in range(n))
		for j in range(n):
			tempsum = sum(C[i,j]*x[i] for i in range(n))
			m.add_constraint(z[j] <= tempsum - L0[j]*(1-x[j]))
			if lhs_constraints:
				m.add_constraint(z[j] >= tempsum - U0[j]*(1-x[j]))
		m.maximize(m.sum(c[j]*x[j] + z[j] for j in range(n)))

	elif(constraints=="sub1" or constraints=="sub2"):
		#can make one of 2 substitutions using slack variables to further reduce # of constraints
		s = m.continuous_var_list(keys=n,lb=0)
		for j in range(n):
			tempsum = sum(C[i,j]*x[i] for i in range(n))
			if constraints=="sub1":
				m.add_constraint(s[j] >= U1[j]*x[j] - tempsum + L0[j]*(1-x[j]))
			else:
				m.add_constraint(s[j] >= -U1[j]*x[j] + tempsum - L0[j]*(1-x[j]))
		if constraints=="sub1":
			m.maximize(m.sum(c[i]*x[i] + (U1[i]*x[i]-s[i]) for i in range(n)))
		else:
			m.maximize(sum(c[j]*x[j] for j in range(n)) + sum(sum(C[i,j]*x[i] for i in range(n))-L0[j]*(1-x[j])-s[j] for j in range(n)))
	else:
		raise Exception(constraints + " is not a valid constraint type for glovers")

	#return model
	return [m,setup_time]
Exemplo n.º 30
0
def get_operator(mdl: Model,
                 auto_penalty: bool = True,
                 default_penalty: float = 1e5) -> Tuple[PauliSumOp, float]:
    """Generate Ising Hamiltonian from a model of DOcplex.

    Args:
        mdl: A model of DOcplex for a optimization problem.
        auto_penalty: If true, the penalty coefficient is automatically defined
                             by "_auto_define_penalty()".
        default_penalty: The default value of the penalty coefficient for the constraints.
            This value is used if "auto_penalty" is False.

    Returns:
        Operator for the Hamiltonian and a constant shift for the obj function.
    """

    _validate_input_model(mdl)

    # set the penalty coefficient by _auto_define_penalty() or manually.
    if auto_penalty:
        penalty = _auto_define_penalty(mdl, default_penalty)
    else:
        penalty = default_penalty

    # set a sign corresponding to a maximized or minimized problem.
    # sign == 1 is for minimized problem. sign == -1 is for maximized problem.
    sign = 1
    if mdl.is_maximized():
        sign = -1

    # assign variables of the model to qubits.
    q_d = {}
    index = 0
    for i in mdl.iter_variables():
        if i in q_d:
            continue
        q_d[i] = index
        index += 1

    # initialize Hamiltonian.
    num_nodes = len(q_d)
    pauli_list = []
    shift = 0.
    zero = np.zeros(num_nodes, dtype=np.bool)

    # convert a constant part of the object function into Hamiltonian.
    shift += mdl.get_objective_expr().get_constant() * sign

    # convert linear parts of the object function into Hamiltonian.
    l_itr = mdl.get_objective_expr().iter_terms()
    for j in l_itr:
        z_p = np.zeros(num_nodes, dtype=np.bool)
        index = q_d[j[0]]
        weight = j[1] * sign / 2
        z_p[index] = True

        pauli_list.append([-weight, Pauli(z_p, zero)])
        shift += weight

    # convert quadratic parts of the object function into Hamiltonian.
    q_itr = mdl.get_objective_expr().iter_quads()
    for i in q_itr:
        index1 = q_d[i[0][0]]
        index2 = q_d[i[0][1]]
        weight = i[1] * sign / 4

        if index1 == index2:
            shift += weight
        else:
            z_p = np.zeros(num_nodes, dtype=np.bool)
            z_p[index1] = True
            z_p[index2] = True
            pauli_list.append([weight, Pauli(z_p, zero)])

        z_p = np.zeros(num_nodes, dtype=np.bool)
        z_p[index1] = True
        pauli_list.append([-weight, Pauli(z_p, zero)])

        z_p = np.zeros(num_nodes, dtype=np.bool)
        z_p[index2] = True
        pauli_list.append([-weight, Pauli(z_p, zero)])

        shift += weight

    # convert constraints into penalty terms.
    for constraint in mdl.iter_constraints():
        right_cst = constraint.get_right_expr().get_constant()
        left_cst = constraint.get_left_expr().get_constant()
        constant = float(right_cst - left_cst)

        # constant parts of penalty*(Constant-func)**2: penalty*(Constant**2)
        shift += penalty * constant**2

        # linear parts of penalty*(Constant-func)**2: penalty*(-2*Constant*func)
        for __l in _iter_net_linear_coeffs(constraint):
            z_p = np.zeros(num_nodes, dtype=np.bool)
            index = q_d[__l[0]]
            weight = __l[1]
            z_p[index] = True

            pauli_list.append([penalty * constant * weight, Pauli(z_p, zero)])
            shift += -penalty * constant * weight

        # quadratic parts of penalty*(Constant-func)**2: penalty*(func**2)
        for __l in _iter_net_linear_coeffs(constraint):
            for l_2 in _iter_net_linear_coeffs(constraint):
                index1 = q_d[__l[0]]
                index2 = q_d[l_2[0]]
                weight1 = __l[1]
                weight2 = l_2[1]
                penalty_weight1_weight2 = penalty * weight1 * weight2 / 4

                if index1 == index2:
                    shift += penalty_weight1_weight2
                else:
                    z_p = np.zeros(num_nodes, dtype=np.bool)
                    z_p[index1] = True
                    z_p[index2] = True
                    pauli_list.append(
                        [penalty_weight1_weight2,
                         Pauli(z_p, zero)])

                z_p = np.zeros(num_nodes, dtype=np.bool)
                z_p[index1] = True
                pauli_list.append([-penalty_weight1_weight2, Pauli(z_p, zero)])

                z_p = np.zeros(num_nodes, dtype=np.bool)
                z_p[index2] = True
                pauli_list.append([-penalty_weight1_weight2, Pauli(z_p, zero)])

                shift += penalty_weight1_weight2

    # Remove paulis whose coefficients are zeros.
    opflow_list = [(pauli[1].to_label(), pauli[0]) for pauli in pauli_list]
    qubit_op = PauliSumOp.from_list(opflow_list)

    return qubit_op, shift
Exemplo n.º 31
0
def qsap_standard(qsap, lhs_constraints=False, **kwargs):
	"""
	standard linearization for the quadratic semi-assignment problem
	"""
	n = qsap.n
	m = qsap.m
	e = qsap.e
	c = qsap.c

	#create model and add variables
	mdl = Model(name='qsap_standard_linearization')
	x = mdl.binary_var_matrix(m,n,name="binary_var")
	w = np.array([[[[mdl.continuous_var() for i in range(n)]for j in range(m)]
						for k in range(n)]for l in range(m)])

	mdl.add_constraints((sum(x[i,k] for k in range(n)) == 1) for i in range(m))

	#add auxiliary constraints
	for i in range(m-1):
		for k in range(n):
			for j in range(i+1,m):
				for l in range(n):
					if lhs_constraints:
						if c[i,k,j,l]+c[j,l,i,k] > 0:
							mdl.add_constraint(w[i,k,j,l] <= x[i,k])
							mdl.add_constraint(w[i,k,j,l] <= x[j,l])
						else:
							mdl.add_constraint(x[i,k] + x[j,l] - 1 <= w[i,k,j,l])
							mdl.add_constraint(w[i,k,j,l] >= 0)
					else:
						mdl.add_constraint(w[i,k,j,l] <= x[i,k])
						mdl.add_constraint(w[i,k,j,l] <= x[j,l])
						mdl.add_constraint(x[i,k] + x[j,l] - 1 <= w[i,k,j,l])
						mdl.add_constraint(w[i,k,j,l] >= 0)


	#TODO make sure this works w/ lhs, mixed sign and non ut

	#compute quadratic values contirbution to obj
	quadratic_values = 0
	for i in range(m-1):
		for k in range(n):
			for j in range(i+1,m):
				for l in range(n):
					quadratic_values = quadratic_values + ((c[i,k,j,l]+c[j,l,i,k])*(w[i,k,j,l]))

	linear_values = mdl.sum(x[i,k]*e[i,k] for k in range(n) for i in range(m))
	mdl.maximize(linear_values + quadratic_values)

	#return model. no setup time for std
	return [mdl, 0]
nb_ambulances = int(read[1][0])

accidents = pd.read_csv("predicted-accidents.csv",
                        engine='c',
                        header=0,
                        skipinitialspace=True)

locations_prob = {
    NamedPoint(float(t.LONGITUDE), float(t.LATITUDE)): float(t.accident_prob)
    for t in accidents.itertuples(index=False)
}

from docplex.mp.model import Model

mdl = Model("accidents")

locations = locations_prob.keys()
ambulance_locations = locations
ambulance_vars = mdl.binary_var_dict(ambulance_locations)
link_vars = mdl.binary_var_matrix(ambulance_locations, locations)

# 1st constraint: each library must be linked to a coffee shop that is open.
mdl.add_constraints(link_vars[c_loc, b] <= ambulance_vars[c_loc]
                    for b in locations for c_loc in ambulance_locations)

# 2nd constraint: each library is linked to exactly one coffee shop.
mdl.add_constraints(
    mdl.sum(link_vars[c_loc, b] for c_loc in ambulance_locations) == 1
    for b in locations)
Exemplo n.º 33
0
def qsap_glovers(qsap, bounds="original", constraints="original", lhs_constraints=False, **kwargs):
	n = qsap.n
	m = qsap.m
	e = qsap.e
	c = qsap.c
	mdl = Model(name='qsap_glovers')
	x = mdl.binary_var_matrix(keys1=m,keys2=n,name="binary_var")
	mdl.add_constraints((sum(x[i,k] for k in range(n)) == 1) for i in range(m))

	U1 = np.zeros((m,n))
	L0 = np.zeros((m,n))
	U0 = np.zeros((m,n))
	L1 = np.zeros((m,n))
	start = timer()

	if bounds=="original":
		for j in range(m):
			for l in range(n):
				col = c[:,:,j,l]
				pos_take_vals = col > 0
				pos_take_vals[j,l] = True
				U1[j,l] = np.sum(col[pos_take_vals])
				neg_take_vals = col < 0
				neg_take_vals[j,l] = False
				L0[j,l] = np.sum(col[neg_take_vals])
				if lhs_constraints:
					U0[j,l] = U1[j,l] - col[j,l]
					L1[j,l] = L0[j,l] + col[j,l]
	elif bounds=="tight" or bounds=="tighter":
		bound_mdl = Model(name="u_bound_m")

		if bounds=="tight":
			bound_x = bound_mdl.continuous_var_matrix(keys1=m,keys2=n,ub=1,lb=0)
		elif bounds == "tighter":
			bound_x = bound_mdl.binary_var_matrix(keys1=m,keys2=n)

		bound_mdl.add_constraints((sum(bound_x[i,k] for k in range(n)) == 1) for i in range(m))

		for j in range(m):
			for l in range(n):
				# solve for upper bound U1
				bound_mdl.set_objective(sense="max", expr=sum(c[i,k,j,l]*bound_x[i,k] for i in range(m) for k in range(n) if i != j))
				u_con = bound_mdl.add_constraint(bound_x[j,l]==1)
				bound_mdl.solve()
				U1[j,l] = bound_mdl.objective_value
				bound_mdl.remove_constraint(u_con)

				# solve for lower bound L0
				bound_mdl.set_objective(sense="min", expr=sum(c[i,k,j,l]*bound_x[i,k] for i in range(m) for k in range(n) if i != j))
				l_con = bound_mdl.add_constraint(bound_x[j,l]==0)
				bound_mdl.solve()
				L0[j,l] = bound_mdl.objective_value
				bound_mdl.remove_constraint(l_con)

				if lhs_constraints:
					# solve for upper bound U0
					bound_mdl.set_objective(sense="max", expr=sum(c[i,k,j,l]*bound_x[i,k] for i in range(m) for k in range(n) if i != j))
					u_con = bound_mdl.add_constraint(bound_x[j,l] == 0)
					bound_mdl.solve()
					bound_mdl.remove_constraint(u_con)
					U0[i,k] = bound_mdl.objective_value

					# solve for lower bound L1
					bound_mdl.set_objective(sense="min", expr=sum(c[i,k,j,l]*bound_x[i,k] for i in range(m) for k in range(n) if i != j))
					l_con = bound_mdl.add_constraint(bound_x[j,l] == 1)
					bound_mdl.solve()
					L1[i,k] = bound_mdl.objective_value
					bound_mdl.remove_constraint(l_con)
		# end bound model
		bound_mdl.end()
	else:
		raise Exception(bounds + " is not a valid bound type for glovers")

	end = timer()
	setup_time = end-start

	#add auxiliary constrains
	if constraints=="original":
		z = mdl.continuous_var_matrix(keys1=m,keys2=n,lb=-mdl.infinity)
		mdl.add_constraints(z[j,l] <= x[j,l]*U1[j,l] for j in range(m) for l in range(n))
		mdl.add_constraints(z[j,l] <= sum(c[i,k,j,l]*x[i,k] for i in range(m) for k in range(n) if i != j)-L0[j,l]*(1-x[j,l]) for j in range(m) for l in range(n))
		if lhs_constraints:
			mdl.add_constraints(z[j,l] >= x[j,l]*L1[j,l] for i in range(m) for k in range(n))
			mdl.add_constraints(z[j,l] >= sum(sum(c[i,k,j,l]*x[i,k] for l in range(n)) for j in range(m))
										-U0[j,l]*(1-x[j,l]) for i in range(m) for k in range(n))

		mdl.maximize(sum(sum(e[i,k]*x[i,k] + z[i,k] for k in range(n)) for i in range(m)))
	elif constraints=="sub1":
		s = mdl.continuous_var_matrix(keys1=m,keys2=n,lb=0)
		mdl.add_constraints(s[j,l] >= U1[j,l]*x[j,l]+L0[j,l]*(1-x[j,l])-sum(c[i,k,j,l]*x[i,k] for i in range(m) for k in range(n) if i != j)
						for l in range(n) for j in range(m))
		mdl.maximize(sum(e[i,k]*x[i,k] for k in range(n) for i in range(m))
					+ sum(U1[i,k]*x[i,k]-s[i,k] for k in range(n) for i in range(m)))
	elif constraints=="sub2":
		s = mdl.continuous_var_matrix(keys1=m,keys2=n,lb=0)
		mdl.add_constraints(s[j,l] >= -L0[j,l]*(1-x[j,l])-(x[j,l]*U1[j,l])+sum(c[i,k,j,l]*x[i,k] for i in range(m) for k in range(n) if i != j)
		 				for j in range(m) for l in range(n))

		mdl.maximize(sum(sum(e[j,l]*x[j,l] for l in range(n))for j in range(m))
					+ sum(sum(-s[j,l]-(L0[j,l]*(1-x[j,l])) + sum(sum(c[i,k,j,l]*x[i,k] for k in range(n))
					for i in range(m)) for l in range(n)) for j in range(m)))
	else:
		raise Exception(constraints + " is not a valid constraint type for glovers")

	#return model
	return [mdl,setup_time]
Exemplo n.º 34
0
def build_diet_model(**kwargs):
    # Create tuples with named fields for foods and nutrients

    food = [Food(*f) for f in FOODS]
    nutrients = [Nutrient(*row) for row in NUTRIENTS]

    food_nutrients = {(fn[0], nutrients[n].name): fn[1 + n]
                      for fn in FOOD_NUTRIENTS for n in range(len(NUTRIENTS))}

    # Model
    mdl = Model(name='diet', **kwargs)

    # Decision variables, limited to be >= Food.qmin and <= Food.qmax
    qty = {
        f: mdl.continuous_var(lb=f.qmin, ub=f.qmax, name=f.name)
        for f in food
    }

    # Limit range of nutrients, and mark them as KPIs
    for n in nutrients:
        amount = mdl.sum(qty[f] * food_nutrients[f.name, n.name] for f in food)
        mdl.add_range(n.qmin, amount, n.qmax)
        mdl.add_kpi(amount, publish_name="Total %s" % n.name)

    # Minimize cost
    mdl.minimize(mdl.sum(qty[f] * f.unit_cost for f in food))

    mdl.print_information()
    return mdl
Exemplo n.º 35
0
	def rlt1_qsap(qsap):
		n = qsap.n
		m = qsap.m
		e = qsap.e
		c = qsap.c

		#create model and add variables
		mdl = Model(name='qsap_rlt1_linearization')
		x = mdl.continuous_var_matrix(m,n,name="binary_var", lb=0, ub=1)
		w = np.array([[[[mdl.continuous_var() for i in range(n)]for j in range(m)]
							for k in range(n)]for l in range(m)])

		# Include the original assignment constraints
		mdl.add_constraints((sum(x[i,k] for k in range(n)) == 1) for i in range(m))

		# Multiply each assignment constraint by each x_jl
		for j in range(m):
			for l in range(n):
				for i in range(m):
					if i == j:
						continue
					mdl.add_constraint(sum(w[i,k,j,l] for k in range(n)) == x[j,l])

		# Add symmetry constraints
		for i in range(m-1):
			for k in range(n):
				for j in range(i+1,m):
					for l in range(n):
						const_name = 'sym_' + str(i) + '_' + str(k) + '_' + str(j)+ '_' + str(l)
						mdl.add_constraint(w[i,k,j,l] == w[j,l,i,k], ctname = const_name)

		# Construct objective value
		quadratic_values = 0
		for i in range(m):
			for j in range(m):
				for k in range(n):
					for l in range(n):
						quadratic_values = quadratic_values + c[i,k,j,l]*w[i,k,j,l]

		linear_values = mdl.sum(x[i,k]*e[i,k] for k in range(n) for i in range(m))
		mdl.maximize(linear_values + quadratic_values)

		# Return model
		return mdl