Python pulp.value() Examples

The following are 22 code examples of pulp.value(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module pulp , or try the search function .
Example #1
Source File: lp.py    From scikit-criteria with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def solve(self):
        super(_LP, self).solve()
        objective = pulp.value(self.objective)
        variables, values = [], []
        for v in self.variables():
            variables.append(v.name)
            values.append(v.varValue)
        status = pulp.LpStatus[self.status]
        self.assignVarsVals(dict.fromkeys(variables, None))
        return Result(status_code=self.status,
                      status=status,
                      objective=objective,
                      variables=variables,
                      values=values)


# =============================================================================
# CONCRETE CLASS
# ============================================================================= 
Example #2
Source File: simulated_feedback.py    From acl2017-interactive_summarizer with Apache License 2.0 6 votes vote down vote up
def __apply_initial_weights_override__(self, weights_override={}, clear_before_override=None):
        """

        :param clear_before_override: bool: if True, all weights are set to a default value, no matter what.
        :param weights_override:
        """
        if (weights_override):
            if clear_before_override is not None:
                print("Clearing summarizer weights")
                for k, v in self.summarizer.weights.iteritems():
                    self.summarizer.weights[k] = float(clear_before_override)
            print("Overriding weights")
            for k, v in weights_override.iteritems():
                if self.summarizer.weights.has_key(k):
                    print("Overriding summarizer weight for '%s' with '%s' (was '%s')" % (
                    k, v, self.summarizer.weights[k]))
                    self.summarizer.weights[k] = v 
Example #3
Source File: wordmoverdist.py    From PyShortTextCategorization with MIT License 6 votes vote down vote up
def word_mover_distance(first_sent_tokens, second_sent_tokens, wvmodel, distancefunc=euclidean, lpFile=None):
    """ Compute the Word Mover's distance (WMD) between the two given lists of tokens.

    Using methods of linear programming, supported by PuLP, calculate the WMD between two lists of words. A word-embedding
    model has to be provided. WMD is returned.

    Reference: Matt J. Kusner, Yu Sun, Nicholas I. Kolkin, Kilian Q. Weinberger, "From Word Embeddings to Document Distances," *ICML* (2015).

    :param first_sent_tokens: first list of tokens.
    :param second_sent_tokens: second list of tokens.
    :param wvmodel: word-embedding models.
    :param distancefunc: distance function that takes two numpy ndarray.
    :param lpFile: log file to write out.
    :return: Word Mover's distance (WMD)
    :type first_sent_tokens: list
    :type second_sent_tokens: list
    :type wvmodel: gensim.models.keyedvectors.KeyedVectors
    :type distancefunc: function
    :type lpFile: str
    :rtype: float
    """
    prob = word_mover_distance_probspec(first_sent_tokens, second_sent_tokens, wvmodel,
                                        distancefunc=distancefunc, lpFile=lpFile)
    return pulp.value(prob.objective) 
Example #4
Source File: lp.py    From DeepConcolic with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def find_constrained_input(self, problem: pulp.LpProblem,
                             metric: PulpLinearMetric,
                             x: np.ndarray,
                             name_prefix = 'x_0_0'):

    d_var = LpVariable(metric.dist_var_name,
                       lowBound = metric.draw_lower_bound (),
                       upBound = metric.upper_bound)
    problem += d_var

    in_vars = self.input_layer_encoder.pulp_in_vars ()
    assert (in_vars.shape == x.shape)
    metric.pulp_constrain (problem, d_var, in_vars, x, name_prefix)

    tp1 ('LP solving: {} constraints'.format(len(problem.constraints)))
    problem.solve (self.solver)
    tp1 ('Solved!')

    if LpStatus[problem.status] != 'Optimal':
      return None

    res = np.zeros(in_vars.shape)
    for idx, var in np.ndenumerate (in_vars):
      res[idx] = pulp.value (var)

    return pulp.value(problem.objective), res


# --- 
Example #5
Source File: envelopment_model_base.py    From pyDEA with MIT License 6 votes vote down vote up
def _process_duals(self, dmu_code, categories, func):
        ''' Helper function that adds duals to solution using given method func.
            Helps to avoid code duplication.

            Args:
                dmu_code (str): DMU code under consideration.
                categories (list of str): list of either input or output
                    categories.
                func (function): a function that accepts DMU code, category and
                    dual variable value and adds it to solution.
        '''
        for category in categories:
            constraint_name = self._constraints[category]
            dual = self._concrete_model.process_dual_value(
                self.lp_model.constraints[constraint_name].pi)
            func(dmu_code, category, dual) 
Example #6
Source File: multiplier_model_base.py    From pyDEA with MIT License 6 votes vote down vote up
def _get_efficiency_score(self, lambda_variable):
        ''' Returns efficiency score based on a given lambda variable.

            Args:
                lambda_variable (double): value of the lambda variable.

            Returns:
                double: efficiency spyDEA.core.
        '''
        eff_score = self._concrete_model.process_obj_var(pulp.value(
            self.lp_model.objective))
        # None is possible when objective function is zero
        if eff_score is None:
            eff_score = 0
        if is_efficient(eff_score, lambda_variable):
            eff_score = 1
        return eff_score 
Example #7
Source File: lp_solve.py    From RevPy with MIT License 5 votes vote down vote up
def get_allocations(x, product_names, out_shape):
    """Return allocations after solving of LP and reshape them."""
    allocations = [x[it].value() for it in product_names]
    return np.array(allocations).reshape(out_shape) 
Example #8
Source File: simulated_feedback.py    From acl2017-interactive_summarizer with Apache License 2.0 5 votes vote down vote up
def get_details(self, iteration, summary_length, oracle_type):
        """
            Get details about an ilp iteration. It does actually recalc the weights, solve the ilp, extract the
            relevant information, and resets the weights to the previous value.
        :param iteration:
        :param summary_length:
        :param oracle_type:
        :return:
        """
        
        print("flight rec: (T: %s = A: %s + R: %s ), (L: %s = A: %s + R: %s)" %
              (len(self.flight_recorder.union().accept | self.flight_recorder.union().reject),
               len(self.flight_recorder.union().accept),
               len(self.flight_recorder.union().reject),
               len(self.flight_recorder.latest().accept | self.flight_recorder.latest().reject),
               len(self.flight_recorder.latest().accept),
               len(self.flight_recorder.latest().reject)))
        # solve the ilp model
        value, subset = self.summarizer.solve_ilp_problem(summary_size=int(summary_length), units="WORDS")
        summary = [self.summarizer.sentences[j].untokenized_form for j in subset]

        summary_text = '\n'.join(summary)
        score = self.rouge(summary_text, self.models, self.summary_length)

        accepted = self.flight_recorder.latest().accept
        rejected = self.flight_recorder.latest().reject
        row = [str(iteration), score[0], score[1], score[2], len(accepted), len(rejected),
               summary_text]

        #self.summarizer.weights = old_weights

        print(row[:-1])
        # print(summary_text.encode('utf-8'))
        self.info_data.append(row)
        return summary, score, subset 
Example #9
Source File: simulated_feedback.py    From acl2017-interactive_summarizer with Apache License 2.0 5 votes vote down vote up
def __init__(self, language, rouge, embeddings={}, fvector=[], ngrams_size=2, top_n=100, dump_base_dir=tempfile.mkdtemp(prefix="simufee-")):
        '''
        Initialize the docs and models structure
        '''
        self.Oracle = Oracle()  # oracle
        self.SumeWrap = SumeWrap(language) # only used to load the sentences and push them into self.summarizer
        self.summarizer = sume.ConceptBasedILPSummarizer(" ", language)
        self.N = ngrams_size # how many words an should the ngrams consist of
        self.top_n = top_n  # currently unused
        self.ref_ngrams = set() # set of ngrams that are in the reference summaries (for the feedback to peek)
        self.ref_phrases = set() # set of phrases that are in the reference summaries (for the feedback to peek)

        self.flight_recorder = FlightRecorder()  # The flight-recorder stores all interactions wrt to concepts (eg. accepted, and rejected)

        self.info_data = [] # stats for the pipeline. The only thing that leaves this class
        self.initial_weights = {} # oracle reweighting
        self.language = language # document language. relevant for stemmer, embeddings, stopwords, parsing
        #self.stemmer = SnowballStemmer(self.language)
        if self.language == "english":
            self.stemmer = SnowballStemmer(self.language)
            #elf.stemmer = WordNetLemmatizer()
        else:
            self.stemmer = SnowballStemmer(self.language)
        self.stoplist = set(stopwords.words(self.language))
        self.rouge = rouge
        self.cluster_size = 0.0
        self.embeddings = embeddings # word2vec embeddings
        self.fvector = fvector # List of support vectors for active learning SVM
        self.pos_hash = {} # active learning // SVM
        self.concept_vec_idx = {} # active learning // SVM
        self.index_vec_concept = {} # active learning // SVM

        ### previously uninitialized fields...
        self.data = None # np.array(self.fvector)   # active learning // SVM TODO rename self.data to somehting that contains svm...
        self.labels = None # active learning // SVM
        self.MAX_WEIGHT = None # int with # of documents (i.e. largest possible DF value)
        self.models = None # reference summaries, only needed for rouge score (as they are converted merged into one large summary)
        self.parse_type = None # None or "parse"
        self.prev_score = None # rouge scores of previous iteration.
        self.score = None # rouge scores of current iteration.
        self.summary_length = None # target summary length.
        self.ub_score = None # rouge scores of upper bound
        self.uncertainity = {} # active learning // SVM

        # graph based propagation settings
        self.graph = PageRankFeedbackGraph(self.stemmer, self.language)
        # self.graph = SimpleNgramFeedbackGraph(self.stemmer, self.language, N=5)
        self.debug_dump_target_dir = dump_base_dir
        self.allowed_number_of_feedback_per_iteration=5 
Example #10
Source File: chemistry.py    From chempy with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def _solve_balancing_ilp_pulp(A):
    import pulp
    x = [pulp.LpVariable('x%d' % i, lowBound=1, cat='Integer') for i in range(A.shape[1])]
    prob = pulp.LpProblem("chempy balancing problem", pulp.LpMinimize)
    prob += reduce(add, x)
    for expr in [pulp.lpSum([x[i]*e for i, e in enumerate(row)]) for row in A.tolist()]:
        prob += expr == 0
    prob.solve()
    return [pulp.value(_) for _ in x] 
Example #11
Source File: chemistry.py    From chempy with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def composition_violation(self, substances, composition_keys=None):
        """ Net amount of constituent produced

        If composition keys correspond to conserved entities e.g. atoms
        in chemical reactions, this function should return a list of zeros.

        Parameters
        ----------
        substances : dict
        composition_keys : iterable of str, ``None`` or ``True``
            When ``None`` or True: composition keys are taken from substances.
            When ``True`` the keys are also return as an extra return value

        Returns
        -------
        - If ``composition_keys == True``: a tuple: (violations, composition_keys)
        - Otherwise: violations (list of coefficients)

        """
        keys, values = zip(*substances.items())
        ret_comp_keys = composition_keys is True
        if composition_keys in (None, True):
            composition_keys = Substance.composition_keys(values)
        net = [0]*len(composition_keys)
        for substance, coeff in zip(values, self.net_stoich(keys)):
            for idx, key in enumerate(composition_keys):
                net[idx] += substance.composition.get(key, 0) * coeff
        if ret_comp_keys:
            return net, composition_keys
        else:
            return net 
Example #12
Source File: chemistry.py    From chempy with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def mass(self, value):
        self.data['mass'] = value 
Example #13
Source File: lp_solve.py    From RevPy with MIT License 5 votes vote down vote up
def solve_lp(prob):
    """Solve LP, return min/max."""
    optimization_result = prob.solve()
    assert optimization_result == pulp.LpStatusOptimal
    optimal_value = pulp.value(prob.objective)

    return optimal_value 
Example #14
Source File: solver.py    From sixcells with GNU General Public License v3.0 5 votes vote down vote up
def solve_simple(scene):
    for cur in itertools.chain(scene.all_cells, scene.all_columns):
        if isinstance(cur, Cell) and cur.display is Cell.unknown:
            continue
        if cur.value is not None and any(x.display is Cell.unknown for x in cur.members):
            # Fill up remaining fulls
            if cur.value == sum(1 for x in cur.members if x.display is not Cell.empty):
                for x in cur.members:
                    if x.display is Cell.unknown:
                        yield x, Cell.full
            # Fill up remaining empties
            if len(cur.members)-cur.value == sum(1 for x in cur.members if x.display is not Cell.full):
                for x in cur.members:
                    if x.display is Cell.unknown:
                        yield x, Cell.empty 
Example #15
Source File: simplex_test.py    From GiMPy with Eclipse Public License 1.0 5 votes vote down vote up
def solve(g):
    el = g.get_edge_list()
    nl = g.get_node_list()
    p = LpProblem('min_cost', LpMinimize)
    capacity = {}
    cost = {}
    demand = {}
    x = {}
    for e in el:
        capacity[e] = g.get_edge_attr(e[0], e[1], 'capacity')
        cost[e] = g.get_edge_attr(e[0], e[1], 'cost')
    for i in nl:
        demand[i] = g.get_node_attr(i, 'demand')
    for e in el:
        x[e] = LpVariable("x"+str(e), 0, capacity[e])
    # add obj
    objective = lpSum (cost[e]*x[e] for e in el)
    p += objective
    # add constraints
    for i in nl:
        out_neig = g.get_out_neighbors(i)
        in_neig = g.get_in_neighbors(i)
        p += lpSum(x[(i,j)] for j in out_neig) -\
             lpSum(x[(j,i)] for j in in_neig)==demand[i]
    p.solve()
    return x, value(objective) 
Example #16
Source File: envelopment_model_base.py    From pyDEA with MIT License 5 votes vote down vote up
def _fill_solution(self, dmu_code, model_solution):
        ''' Fills given solution with data calculated for one DMU.

            Args:
                dmu_code (str): DMU code for which the LP was solved.
                model_solution (Solution): object where solution for one DMU
                    will be written.
        '''
        model_solution.orientation = self._concrete_model.get_orientation()
        model_solution.add_lp_status(dmu_code, self.lp_model.status)

        if self.lp_model.status == pulp.LpStatusOptimal:
            lambda_variables = dict()
            for dmu in self.input_data.DMU_codes:
                var = self._variables.get(dmu, None)
                if (var is not None and var.varValue is not None and
                        abs(var.varValue) > ZERO_TOLERANCE):
                    lambda_variables[dmu] = var.varValue

            if self._should_add_efficiency:
                model_solution.add_efficiency_score(
                    dmu_code, self._concrete_model.process_obj_var
                    (pulp.value(self.lp_model.objective)))
                
            model_solution.add_lambda_variables(dmu_code, lambda_variables)
            self._process_duals(dmu_code, self.input_data.input_categories,
                                model_solution.add_input_dual)
            self._process_duals(dmu_code, self.input_data.output_categories,
                                model_solution.add_output_dual) 
Example #17
Source File: space.py    From qmpy with MIT License 5 votes vote down vote up
def compute_stabilities(self, phases=None, save=False, reevaluate=True):
        """
        Calculate the stability for every Phase.

        Keyword Arguments:
            phases:
                List of Phases. If None, uses every Phase in PhaseSpace.phases

            save:
                If True, save the value for stability to the database. 

            new_only:
                If True, only compute the stability for Phases which did not
                import a stability from the OQMD. False by default.
        """
        from qmpy.analysis.vasp.calculation import Calculation
        if phases is None:
            phases = self.phases

        if reevaluate:
            for p in self.phases:
                p.stability = None

        for p in phases:
            if p.stability is None:
                if p in self.phase_dict.values():
                    self.compute_stability(p)
                else:
                    p2 = self.phase_dict[p.name]
                    if p2.stability is None:
                        self.compute_stability(p2)
                    base = max(0, p2.stability)
                    diff = p.energy - p2.energy
                    p.stability = base + diff

            if save:
                qs = qmpy.FormationEnergy.objects.filter(id=p.id)
                qs.update(stability=p.stability) 
Example #18
Source File: space.py    From qmpy with MIT License 5 votes vote down vote up
def get_minima(self, phases, bounds):
        """
        Given a set of Phases, get_minima will determine the minimum
        free energy elemental composition as a weighted sum of these
        compounds
        """

        prob = pulp.LpProblem('GibbsEnergyMin', pulp.LpMinimize)
        pvars = pulp.LpVariable.dicts('phase', phases, 0)
        bvars = pulp.LpVariable.dicts('bound', bounds, 0.0, 1.0)
        prob += pulp.lpSum( self.phase_energy(p)*pvars[p] for p in phases ) - \
                pulp.lpSum( self.phase_energy(bound)*bvars[bound] for bound in bounds ), \
                                "Free Energy"
        for elt in self.bound_space:
            prob += sum([ p.unit_comp.get(elt,0)*pvars[p] for p in phases ])\
                        == \
                sum([ b.unit_comp.get(elt, 0)*bvars[b] for b in bounds ]),\
                            'Contraint to the proper range of'+elt
        prob += sum([ bvars[b] for b in bounds ]) == 1, \
                'sum of bounds must be 1'

        if pulp.GUROBI().available():
            prob.solve(pulp.GUROBI(msg=False))
        elif pulp.COIN_CMD().available():
            prob.solve(pulp.COIN_CMD())
        elif pulp.COINMP_DLL().available():
            prob.solve(pulp.COINMP_DLL())
        else:
            prob.solve()

        E = pulp.value(prob.objective)
        xsoln = defaultdict(float,
            [(p, pvars[p].varValue) for p in phases if
                abs(pvars[p].varValue) > 1e-4])
        return xsoln, E 
Example #19
Source File: optimization_model_pulp.py    From optimization-tutorial with MIT License 5 votes vote down vote up
def _create_main_constraints(self):
        # Depending on what you need, you may want to consider creating any of
        # the expressions (constraints or objective terms) as an attribute of
        # the OptimizationModel class (e.g. self.inv_balance_constraints).
        # That way if, for example, at the end of the optimization you need to check
        # the slack variables of certain constraints, you know they already exists in your model

        # ================== Inventory balance constraints ==================
        self.inv_balance_constraints = {
            period: add_constr(self.model, pulp.LpConstraint(
                e=self.inventory_variables[period - 1] + self.production_variables[period]
                  - self.inventory_variables[period],
                sense=pulp.LpConstraintEQ,
                name='inv_balance' + str(period),
                rhs=value.demand))
            for period, value in self.input_data.iloc[1:].iterrows()}

        # inv balance for first period
        self.first_period_inv_balance_constraints = add_constr(self.model, pulp.LpConstraint(
            e=self.production_variables[0] - self.inventory_variables[0],
            sense=pulp.LpConstraintEQ,
            name='inv_balance0',
            rhs=self.input_data.iloc[0].demand - self.input_params['initial_inventory']))

        # ================== Production capacity constraints ==================
        self.production_capacity_constraints = {
            index: add_constr(self.model, pulp.LpConstraint(
                e=value,
                sense=pulp.LpConstraintLE,
                name='prod_cap_month_' + str(index),
                rhs=self.input_data.iloc[index].production_capacity))
            for index, value in self.production_variables.items()}

    # ================== Costs and objective function ================== 
Example #20
Source File: space.py    From qmpy with MIT License 4 votes vote down vote up
def get_reaction(self, var, facet=None):
        """
        For a given composition, what is the maximum delta_composition reaction
        on the given facet. If None, returns the whole reaction for the given
        PhaseSpace.

        Examples::

            >>> space = PhaseSpace('Fe2O3-Li2O')
            >>> equilibria = space.hull[0]
            >>> space.get_reaction('Li2O', facet=equilibria)

        """

        if isinstance(var, basestring):
            var = parse_comp(var)

        if facet:
            phases = facet
        else:
            phases = self.stable

        prob = pulp.LpProblem('BalanceReaction', pulp.LpMaximize)
        pvars = pulp.LpVariable.dicts('prod', phases, 0)
        rvars = pulp.LpVariable.dicts('react', phases, 0)
        prob += sum([ p.fraction(var)['var']*pvars[p] for p in phases ])-\
                sum([ p.fraction(var)['var']*rvars[p] for p in phases ]),\
                "Maximize delta comp"
        for celt in self.space:
            prob += sum([ p.fraction(var)[celt]*pvars[p] for p in phases ]) ==\
                    sum([ p.fraction(var)[celt]*rvars[p] for p in phases ]),\
                    'identical %s composition on both sides' % celt
        prob += sum([ rvars[p] for p in phases ]) == 1
        
        if pulp.GUROBI().available():
            prob.solve(pulp.GUROBI(msg=False))
        elif pulp.COIN_CMD().available():
            prob.solve(pulp.COIN_CMD())
        elif pulp.COINMP_DLL().available():
            prob.solve(pulp.COINMP_DLL())
        else:
            prob.solve()

        prods = defaultdict(float,[ (c, pvars[c].varValue) for c in phases
            if pvars[c].varValue > 1e-4 ])
        reacts = defaultdict(float,[ (c, rvars[c].varValue) for c in phases
            if rvars[c].varValue > 1e-4 ])
        n_elt = pulp.value(prob.objective)
        return reacts, prods, n_elt 
Example #21
Source File: concept_based.py    From acl2017-interactive_summarizer with Apache License 2.0 4 votes vote down vote up
def prune_concepts(self, method="threshold", value=3, rejected_list=[]):
        """Prune the concepts for efficient summarization.

        Args:
            method (str): the method for pruning concepts that can be whether
              by using a minimal value for concept scores (threshold) or using
              the top-N highest scoring concepts (top-n), defaults to
              threshold.
            value (int): the value used for pruning concepts, defaults to 3.

        """
        if method == 'stopwords':
            concepts = self.weights.keys()
            for concept in concepts:
                pruned_list = prune_ngrams(concept, self.stoplist, 1)
                if not pruned_list:
                    #print concept, self.weights[concept]
                    del self.weights[concept]

        if method == "list":
            concepts = self.weights.keys()
            for concept in concepts:
                if concept in rejected_list:
                    #print concept, self.weights[concept]
                    del self.weights[concept]

        # 'threshold' pruning method
        if method == "threshold":

            # iterates over the concept weights
            concepts = self.weights.keys()
            for concept in concepts:
                if self.weights[concept] < value:
                    del self.weights[concept]

        # 'top-n' pruning method
        elif method == "top-n":

            # sort concepts by scores
            sorted_concepts = sorted(self.weights,
                                     key=lambda x: self.weights[x],
                                     reverse=True)

            # iterates over the concept weights
            concepts = self.weights.keys()
            for concept in concepts:
                if concept not in sorted_concepts[:value]:
                    del self.weights[concept]

        # iterates over the sentences
        for i in range(len(self.sentences)):

            # current sentence concepts
            concepts = self.sentences[i].concepts

            # prune concepts
            self.sentences[i].concepts = [c for c in concepts
                                          if c in self.weights] 
Example #22
Source File: optimization_model_pulp.py    From optimization-tutorial with MIT License 4 votes vote down vote up
def optimize(self):
        """
        Default solver is 'cbc' unless solver is set to something else.
        You may need to provide a path for any of the solvers using 'path' argument.
        """

        if model_params['write_lp']:
            logger.info('Writing the lp file!')
            self.model.writeLP(self.model.name + '.lp')

        logger.info('Optimization starts!')
        _solver = pulp.PULP_CBC_CMD(keepFiles=model_params['write_log'],
                                    fracGap=model_params['mip_gap'],
                                    maxSeconds=model_params['time_limit'],
                                    msg=model_params['display_log'])

        if model_params['solver'] == 'gurobi':
            _solver = pulp.GUROBI(msg=model_params['write_log'],
                                  timeLimit=model_params['time_limit'],
                                  epgap=model_params['mip_gap'])
        elif model_params['solver'] == 'cplex':
            options = []
            if model_params['mip_gap']:
                set_mip_gap = "set mip tolerances mipgap {}".format(model_params['mip_gap'])
                options.append(set_mip_gap)
            _solver = pulp.CPLEX_CMD(keepFiles=model_params['write_log'],
                                     options=options, timelimit=model_params['time_limit'],
                                     msg=model_params['display_log'])
        elif model_params['solver'] == 'glpk':
            # Read more about glpk options: https://en.wikibooks.org/wiki/GLPK/Using_GLPSOL
            options = []
            if model_params['mip_gap']:
                set_mip_gap = "--mipgap {}".format(model_params['mip_gap'])
                options.append(set_mip_gap)
            if model_params['time_limit']:
                set_time_limit = "--tmlim {}".format(model_params['time_limit'])
                options.append(set_time_limit)
            _solver = pulp.GLPK_CMD(keepFiles=model_params['write_log'], options=options,
                                    msg=model_params['display_log'])

        self.model.solve(solver=_solver)

        if self.model.status == pulp.LpStatusOptimal:
            logger.info('The solution is optimal and the objective value '
                        'is ${:,.2f}'.format(pulp.value(self.model.objective)))

    # ================== Output ==================