예제 #1
0
    def apply(self, problem: ParamConeProg) -> Tuple[Dict, Dict]:
        """Returns a new problem and data for inverting the new solution."""
        from ortools.linear_solver import linear_solver_pb2

        # Create data and inv_data objects
        data = {}
        inv_data = {self.VAR_ID: problem.x.id}
        if not problem.formatted:
            problem = self.format_constraints(problem, None)
        data[s.PARAM_PROB] = problem
        data[self.DIMS] = problem.cone_dims

        constr_map = problem.constr_map
        inv_data["constraints"] = constr_map[Zero] + constr_map[NonNeg]

        # Min c'x + d such that Ax + b = s, s \in cones.
        c, d, A, b = problem.apply_parameters()
        A = csr_matrix(A)
        data["num_constraints"], data["num_vars"] = A.shape

        # TODO: Switch to a vectorized model-building interface when one is
        # available in OR-Tools.
        model = linear_solver_pb2.MPModelProto()
        model.objective_offset = d.item() if isinstance(d, np.ndarray) else d
        for var_index, obj_coef in enumerate(c):
            var = linear_solver_pb2.MPVariableProto(
                objective_coefficient=obj_coef, name="x_%d" % var_index)
            model.variable.append(var)

        for row_index in range(A.shape[0]):
            constraint = linear_solver_pb2.MPConstraintProto(
                name="constraint_%d" % row_index)
            start = A.indptr[row_index]
            end = A.indptr[row_index + 1]
            for nz_index in range(start, end):
                col_index = A.indices[nz_index]
                coeff = A.data[nz_index]
                constraint.var_index.append(col_index)
                constraint.coefficient.append(coeff)
            if row_index < problem.cone_dims.zero:
                # a'x + b == 0
                constraint.lower_bound = -b[row_index]
                constraint.upper_bound = -b[row_index]
            else:
                # a'x + b >= 0
                constraint.lower_bound = -b[row_index]
            model.constraint.append(constraint)

        data[self.MODEL_PROTO] = model
        return data, inv_data
예제 #2
0
 def test_proto(self):
     input_proto = linear_solver_pb2.MPModelProto()
     text_format.Merge(TEXT_MODEL, input_proto)
     solver = pywraplp.Solver('solveFromProto',
                              pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)
     # For now, create the model from the proto by parsing the proto
     errors = solver.LoadModelFromProto(input_proto)
     self.assertFalse(errors)
     solver.Solve()
     # Fill solution
     solution = linear_solver_pb2.MPSolutionResponse()
     solver.FillSolutionResponseProto(solution)
     self.assertEqual(solution.objective_value, 3.0)
     self.assertEqual(solution.variable_value[0], 1.0)
     self.assertEqual(solution.variable_value[1], 1.0)
     self.assertEqual(solution.best_objective_bound, 3.0)