Example #1
0
    def __get_model__(self, relaxed=False):
        """Create gurobi API model.
            Args:
            relaxed (:bool:): This flag describes if logic values are relaxed.
                              Default ``False``.
            Example: ``{'TimeLimit': 10}``.
        """
        self.__create_gurobi_model__()
        self.__create_vars__()
        self.__create_objfunc__()
        self.__create_constraints_aux__
        self.__create_constraints__()
        if self.list_y_init is not None:
            self.s[self.I[0], 1].lb = 1

        self.m.update()
        model = solution.Solution(
            self.m,
            dict(s=self.s,
                 tr=self.tr,
                 r=self.r,
                 er=self.er,
                 e=self.e,
                 u=self.u,
                 w=self.w,
                 z=self.z,
                 cr=self.cr,
                 y=self.y,
                 mu=self.mu))
        return model
Example #2
0
    def update_lambda1(self, lambda1, sol):
        """Update lambda in DPP model
            Args:
            lambda1 (:obj:`list`): Array with lambda values.
        """

        self.solution = sol
        self.lambda1 = lambda1
        self.__create_vars__()
        self.__create_objfunc__()
        self.__create_constraints__()
        self.m.update()
        self.model = solution.Solution(
            self.m,
            dict(s=self.s,
                 tr=self.tr,
                 r=self.r,
                 er=self.er,
                 e=self.e,
                 u=self.u,
                 w=self.w,
                 z=self.z,
                 cr=self.cr,
                 y=self.y,
                 mu=self.mu))
Example #3
0
 def set_model(self, model):
     self.model = solution.Solution(
         model,
         dict(s=self.s,
              tr=self.tr,
              r=self.r,
              er=self.er,
              e=self.e,
              u=self.u,
              w=self.w,
              z=self.z,
              cr=self.cr,
              y=self.y,
              mu=self.mu))
Example #4
0
    def gather_solution(self, DPP_sol_row, initial_solution):
        counter = 0
        s = gurobipy.tupledict()
        tr = gurobipy.tupledict()
        r = gurobipy.tupledict()
        er = gurobipy.tupledict()
        e = gurobipy.tupledict()
        Tlen = self.problem_data.get_names("wildfire")
        Ilen = self.problem_data.get_names("resources")
        Glen = self.problem_data.get_names("groups")

        for res in Ilen:
            DPP = DPP_sol_row[counter]
            for tt in Tlen:
                s[res,tt] = DPP.get_variables().get_variable('s')[res,tt].X
                tr[res,tt] = DPP.get_variables().get_variable('tr')[res,tt].X
                r[res,tt] = DPP.get_variables().get_variable('r')[res,tt].X
                er[res,tt] = DPP.get_variables().get_variable('er')[res,tt].X
                e[res,tt] = DPP.get_variables().get_variable('e')[res,tt].X
            counter = counter + 1
        vars = gurobipy.tupledict()
        vars["s"] = s
        vars["tr"] = tr
        vars["r"] = r
        vars["er"] = er
        vars["e"] = e
        modelcopy = initial_solution.get_model().copy()
        modelcopy.update()
        sol1 = _sol.Solution(modelcopy, vars)
        counter=0
        for res in Ilen:
            DPP = DPP_sol_row[counter]
            for tt in Tlen:
                sol1.get_model().getVarByName("start["+res+","+str(tt)+"]").start = DPP.get_variables().get_variable('s')[res,tt].X
                sol1.get_model().getVarByName("travel["+str(res)+","+str(tt)+"]").start = DPP.get_variables().get_variable('tr')[res,tt].X
                sol1.get_model().getVarByName("rest["+str(res)+","+str(tt)+"]").start = DPP.get_variables().get_variable('r')[res,tt].X
                sol1.get_model().getVarByName("end_rest["+str(res)+","+str(tt)+"]").start = DPP.get_variables().get_variable('er')[res,tt].X
                sol1.get_model().getVarByName("end["+str(res)+","+str(tt)+"]").start = DPP.get_variables().get_variable('e')[res,tt].X
            counter = counter + 1
        #for gro in Glen:
        #    for tt in Tlen:
        #        sol1.get_model().getVarByName("missing_resources["+gro+","+str(tt)+"]").start = DPP.get_variables().get_variable('mu')[gro,tt].X
        sol1.get_model().update()
        #print(sol1.get_model().getVars())
        #   mu[res,tt] = DPP.get_variables().get_variable('mu')[res,tt]
        return sol1
Example #5
0
    def model(self,
              data,
              relaxed=False,
              slack_containment=False,
              valid_constraints=None,
              slack_penalty=1000000000000):
        """Wildfire suppression model.

        Args:
            data (:obj:`firedecomp.model.InputModel`): problem data.
            relaxed (:obj:`bool`): if True variables will be continuous. Defaults
                to False.
            slack_containment (:obj:`bool`): if True add slack variable to wildfire
                containment constraints. Defaults to False.
            slack_penalty (:obj:`float`): slack containment penalty.
        """
        self.m = gurobipy.Model("wildfire_supression")

        if relaxed is True:
            vtype = gurobipy.GRB.CONTINUOUS
            lb = 0
            ub = 1
        else:
            vtype = gurobipy.GRB.BINARY
            lb = 0
            ub = 1

        if valid_constraints is None:
            valid_constraints = ['contention', 'work', 'max_obj']

        # Variables
        # =========
        # Resources
        # ---------
        self.s = self.m.addVars(data.I,
                                data.T,
                                vtype=vtype,
                                lb=lb,
                                ub=ub,
                                name="start")
        self.tr = self.m.addVars(data.I,
                                 data.T,
                                 vtype=vtype,
                                 lb=lb,
                                 ub=ub,
                                 name="travel")
        self.r = self.m.addVars(data.I,
                                data.T,
                                vtype=vtype,
                                lb=lb,
                                ub=ub,
                                name="rest")
        self.er = self.m.addVars(data.I,
                                 data.T,
                                 vtype=vtype,
                                 lb=lb,
                                 ub=ub,
                                 name="end_rest")
        self.e = self.m.addVars(data.I,
                                data.T,
                                vtype=vtype,
                                lb=lb,
                                ub=ub,
                                name="end")

        # Auxiliar variables
        self.u = {(i, t): self.s.sum(i, data.T_int.get_names(p_max=t)) -
                  self.e.sum(i, data.T_int.get_names(p_max=t - 1))
                  for i in data.I for t in data.T}
        self.w = {(i, t): self.u[i, t] - self.r[i, t] - self.tr[i, t]
                  for i in data.I for t in data.T}
        self.z = {i: self.e.sum(i, '*') for i in data.I}

        self.cr = {(i, t): sum([
            (t + 1 - t1) * self.s[i, t1] - (t - t1) * self.e[i, t1] -
            self.r[i, t1] - data.WP[i] * self.er[i, t1]
            for t1 in data.T_int.get_names(p_max=t)
        ])
                   for i in data.I for t in data.T
                   if not data.ITW[i] and not data.IOW[i]}

        self.cr.update({
            (i, t):
            (t + data.CWP[i] - data.CRP[i]) * self.s[i, data.min_t] + sum([
                (t + 1 - t1 + data.WP[i]) * self.s[i, t1]
                for t1 in data.T_int.get_names(p_min=data.min_t + 1, p_max=t)
            ]) - sum([(t - t1) * self.e[i, t1] + self.r[i, t1] +
                      data.WP[i] * self.er[i, t1]
                      for t1 in data.T_int.get_names(p_max=t)])
            for i in data.I for t in data.T if data.ITW[i] or data.IOW[i]
        })

        # Wildfire
        # --------
        self.y = self.m.addVars(data.T + [data.min_t - 1],
                                vtype=vtype,
                                lb=lb,
                                ub=ub,
                                name="contention")
        self.mu = self.m.addVars(data.G,
                                 data.T,
                                 vtype=gurobipy.GRB.CONTINUOUS,
                                 lb=0,
                                 name="missing_resources")

        if slack_containment:
            slack_cont1 = self.m.addVar(vtype=gurobipy.GRB.CONTINUOUS,
                                        lb=0,
                                        name="slack_containment_1")
            slack_cont2 = self.m.addVars(data.T,
                                         vtype=gurobipy.GRB.CONTINUOUS,
                                         lb=0,
                                         name="slack_containment_2")

        # Objective
        # =========
        self.obj_expression = \
            sum([data.C[i]*self.u[i, t] for i in data.I for t in data.T]) + \
            sum([data.P[i] * self.z[i] for i in data.I]) + \
            sum([data.NVC[t] * self.y[t-1] for t in data.T]) + \
            sum([data.Mp*self.mu[g, t] for g in data.G for t in data.T]) + \
            0.001*self.y[data.max_t]

        if slack_containment:
            self.obj_expression += \
                slack_penalty * slack_cont1 + \
                sum([slack_penalty * slack_cont2[t] for t in data.T])

        self.m.setObjective(self.obj_expression, gurobipy.GRB.MINIMIZE)

        # Constraints
        # ===========

        # Valid constraints
        # -----------------

        if 'contention' in valid_constraints:
            expr_lhs = {t: self.y[t] for t in data.T}
            expr_rhs = {t: self.y[t - 1] for t in data.T}

            self.m.addConstrs((expr_lhs[t] <= expr_rhs[t] for t in data.T),
                              name='valid_constraint_contention')

        if 'work' in valid_constraints:
            expr_lhs = {(i, t): self.w[i, t] for i in data.I for t in data.T}
            expr_rhs = {t: self.y[t - 1] for t in data.T}

            self.m.addConstrs((expr_lhs[i, t] <= expr_rhs[t] for i in data.I
                               for t in data.T),
                              name='valid_constraint_contention')

        # Wildfire Containment
        # --------------------
        self.m.addConstr(self.y[data.min_t - 1] == 1,
                         name='start_no_contained')

        if slack_containment:
            wildfire_containment_1_expr = \
                sum([data.PER[t] * self.y[t - 1] for t in data.T]) <= \
                sum([data.PR[i, t] * self.w[i, t] for i in data.I for t in data.T]) + \
                slack_cont1
        else:
            wildfire_containment_1_expr = \
                sum([data.PER[t] * self.y[t - 1] for t in data.T]) <= \
                sum([data.PR[i, t] * self.w[i, t] for i in data.I for t in data.T])

        self.m.addConstr(wildfire_containment_1_expr,
                         name='wildfire_containment_1')

        if slack_containment:
            wildfire_containment_2_expr = (
                data.M * self.y[t] + slack_cont2[t] >=
                sum([data.PER[t1]
                     for t1 in data.T_int.get_names(p_max=t)]) * self.y[t - 1]
                - sum([
                    data.PR[i, t1] * self.w[i, t1] for i in data.I
                    for t1 in data.T_int.get_names(p_max=t)
                ]) for t in data.T)
        else:
            wildfire_containment_2_expr = (
                data.M * self.y[t] >=
                sum([data.PER[t1]
                     for t1 in data.T_int.get_names(p_max=t)]) * self.y[t - 1]
                - sum([
                    data.PR[i, t1] * self.w[i, t1] for i in data.I
                    for t1 in data.T_int.get_names(p_max=t)
                ]) for t in data.T)

        self.m.addConstrs(wildfire_containment_2_expr,
                          name='wildfire_containment_2')

        # Start of activity
        # -----------------
        self.m.addConstrs((data.A[i] * self.w[i, t] <= sum(
            [self.tr[i, t1] for t1 in data.T_int.get_names(p_max=t)])
                           for i in data.I for t in data.T),
                          name='start_activity_1')

        self.m.addConstrs((self.s[i, data.min_t] + sum([
            (data.max_t + 1) * self.s[i, t]
            for t in data.T_int.get_names(p_min=data.min_t + 1)
        ]) <= data.max_t * self.z[i] for i in data.I if data.ITW[i] == True),
                          name='start_activity_2')

        self.m.addConstrs((sum([self.s[i, t] for t in data.T]) <= self.z[i]
                           for i in data.I if data.ITW[i] == False),
                          name='start_activity_3')

        # End of Activity
        # ---------------
        self.m.addConstrs((sum([
            self.tr[i, t1]
            for t1 in data.T_int.get_names(p_min=t - data.TRP[i] + 1, p_max=t)
        ]) >= data.TRP[i] * self.e[i, t] for i in data.I for t in data.T),
                          name='end_activity')

        # Breaks
        # ------
        self.m.addConstrs((0 <= self.cr[i, t] for i in data.I for t in data.T),
                          name='Breaks_1_lb')

        self.m.addConstrs(
            (self.cr[i, t] <= data.WP[i] for i in data.I for t in data.T),
            name='Breaks_1_ub')

        self.m.addConstrs((self.r[i, t] <= sum([
            self.er[i, t1]
            for t1 in data.T_int.get_names(p_min=t, p_max=t + data.RP[i] - 1)
        ]) for i in data.I for t in data.T),
                          name='Breaks_2')

        self.m.addConstrs((sum([
            self.r[i, t1]
            for t1 in data.T_int.get_names(p_min=t - data.RP[i] + 1, p_max=t)
        ]) >= data.RP[i] * self.er[i, t] if t >= data.min_t - 1 + data.RP[i]
                           else data.CRP[i] * self.s[i, data.min_t] + sum([
                               self.r[i, t1]
                               for t1 in data.T_int.get_names(p_max=t)
                           ]) >= data.RP[i] * self.er[i, t] for i in data.I
                           for t in data.T),
                          name='Breaks_3')

        self.m.addConstrs((sum([
            self.r[i, t1] + self.tr[i, t1]
            for t1 in data.T_int.get_names(p_min=t - data.TRP[i],
                                           p_max=t + data.TRP[i])
        ]) >= len(
            data.T_int.get_names(p_min=t - data.TRP[i], p_max=t + data.TRP[i]))
                           * self.r[i, t] for i in data.I for t in data.T),
                          name='Breaks_4')

        # Maximum Number of Usage Periods in a Day
        # ----------------------------------------
        self.m.addConstrs((sum([self.u[i, t]
                                for t in data.T]) <= data.UP[i] - data.CUP[i]
                           for i in data.I),
                          name='max_usage_periods')

        # Non-Negligence of Fronts
        # ------------------------
        self.m.addConstrs((sum([self.w[i, t] for i in data.Ig[g]]) >=
                           data.nMin[g, t] * self.y[t - 1] - self.mu[g, t]
                           for g in data.G for t in data.T),
                          name='non-negligence_1')

        self.m.addConstrs(
            (sum([self.w[i, t]
                  for i in data.Ig[g]]) <= data.nMax[g, t] * self.y[t - 1]
             for g in data.G for t in data.T),
            name='non-negligence_2')

        # Logical constraints
        # ------------------------
        self.m.addConstrs(
            (sum([t * self.e[i, t]
                  for t in data.T]) >= sum([t * self.s[i, t] for t in data.T])
             for i in data.I),
            name='logical_1')

        self.m.addConstrs(
            (sum([self.e[i, t] for t in data.T]) <= 1 for i in data.I),
            name='logical_2')

        self.m.addConstrs((self.r[i, t] + self.tr[i, t] <= self.u[i, t]
                           for i in data.I for t in data.T),
                          name='logical_3')

        self.m.addConstrs(
            (sum([self.w[i, t] for t in data.T]) >= self.z[i] for i in data.I),
            name='logical_4')

        self.m.update()

        return solution.Solution(
            self.m,
            dict(s=self.s,
                 tr=self.tr,
                 r=self.r,
                 er=self.er,
                 e=self.e,
                 u=self.u,
                 w=self.w,
                 z=self.z,
                 cr=self.cr,
                 y=self.y,
                 mu=self.mu))
def model(data, relaxed=False):
    """Wildfire suppression model.
    data (:obj:`firedecomp.model.InputModel`): problem data.
    """
    m = scip.Model("wildfire_supression")

    if relaxed is True:
        vtype = "C"
        lb = 0
        ub = 1
    else:
        vtype = "B"
        lb = 0
        ub = 1

    # Variables
    # =========
    # Resources
    # ---------
    s = {}
    tr = {}
    r = {}
    er = {}
    e = {}
    for i in data.I:
        for t in data.T:
            s[i, t] = m.addVar(vtype=vtype,
                               lb=lb,
                               ub=ub,
                               name="start[%s,%s]" % (i, t))
            tr[i, t] = m.addVar(vtype=vtype,
                                lb=lb,
                                ub=ub,
                                name="travel[%s,%s]" % (i, t))
            r[i, t] = m.addVar(vtype=vtype,
                               lb=lb,
                               ub=ub,
                               name="rest[%s,%s]" % (i, t))
            er[i, t] = m.addVar(vtype=vtype,
                                lb=lb,
                                ub=ub,
                                name="end_rest[%s,%s]" % (i, t))
            e[i, t] = m.addVar(vtype=vtype,
                               lb=lb,
                               ub=ub,
                               name="end[%s,%s]" % (i, t))

    # Auxiliar variables
    u = {(i, t):
         scip.quicksum(s[i, tind] for tind in data.T_int.get_names(p_max=t)) -
         scip.quicksum(e[i, tind]
                       for tind in data.T_int.get_names(p_max=t - 1))
         for i in data.I for t in data.T}
    w = {(i, t): u[i, t] - r[i, t] - tr[i, t] for i in data.I for t in data.T}
    z = {i: scip.quicksum(e[i, tind] for tind in data.T) for i in data.I}

    cr = {(i, t): sum([(t + 1 - t1) * s[i, t1] - (t - t1) * e[i, t1] -
                       r[i, t1] - data.WP[i] * er[i, t1]
                       for t1 in data.T_int.get_names(p_max=t)])
          for i in data.I for t in data.T
          if not data.ITW[i] and not data.IOW[i]}

    cr.update({
        (i, t): (t + data.CWP[i] - data.CRP[i]) * s[i, data.min_t] +
        sum([(t + 1 - t1 + data.WP[i]) * s[i, t1]
             for t1 in data.T_int.get_names(p_min=data.min_t + 1, p_max=t)]) -
        sum([(t - t1) * e[i, t1] + r[i, t1] + data.WP[i] * er[i, t1]
             for t1 in data.T_int.get_names(p_max=t)])
        for i in data.I for t in data.T if data.ITW[i] or data.IOW[i]
    })

    # Wildfire
    # --------
    y = {
        t: m.addVar(vtype=vtype, lb=lb, ub=ub, name="contention[%s]" % t)
        for t in data.T + [data.min_t - 1]
    }
    mu = {(g, t): m.addVar(vtype="C",
                           lb=0,
                           name="missing_resources[%s,%s]" % (g, t))
          for g in data.G for t in data.T}

    # Objective
    # =========
    m.setObjective(sum([data.C[i] * u[i, t] for i in data.I for t in data.T]) +
                   sum([data.P[i] * z[i] for i in data.I]) +
                   sum([data.NVC[t] * y[t - 1] for t in data.T]) +
                   sum([data.Mp * mu[g, t] for g in data.G
                        for t in data.T]) + 0.001 * y[data.max_t],
                   sense="minimize")

    # Constraints
    # ===========

    # Wildfire Containment
    # --------------------
    m.addCons(y[data.min_t - 1] == 1, name='start_no_contained')

    m.addCons(sum([data.PER[t] * y[t - 1] for t in data.T]) <= sum(
        [data.PR[i, t] * w[i, t] for i in data.I for t in data.T]),
              name='wildfire_containment_1')

    for t in data.T:
        m.addCons(
            data.M * y[t] >=
            sum([data.PER[t1]
                 for t1 in data.T_int.get_names(p_max=t)]) * y[t - 1] - sum([
                     data.PR[i, t1] * w[i, t1] for i in data.I
                     for t1 in data.T_int.get_names(p_max=t)
                 ]),
            name='wildfire_containment_2[%s]' % t)

    # Start of activity
    # -----------------
    for i in data.I:
        for t in data.T:
            m.addCons(data.A[i] * w[i, t] <= sum(
                [tr[i, t1] for t1 in data.T_int.get_names(p_max=t)]),
                      name='start_activity_1[%s,%s]' % (i, t))

    for i in data.I:
        if data.ITW[i] == True:
            m.addCons(s[i, data.min_t] + sum([
                (data.max_t + 1) * s[i, t]
                for t in data.T_int.get_names(p_min=data.min_t + 1)
            ]) <= data.max_t * z[i],
                      name='start_activity_2[%s]' % i)

    for i in data.I:
        if data.ITW[i] == False:
            m.addCons(sum([s[i, t] for t in data.T]) <= z[i],
                      name='start_activity_3[%s]' % i)

    # End of Activity
    # ---------------
    for i in data.I:
        for t in data.T:
            m.addCons(sum([
                tr[i, t1]
                for t1 in data.T_int.get_names(p_min=t - data.TRP[i] + 1,
                                               p_max=t)
            ]) >= data.TRP[i] * e[i, t],
                      name='end_activity[%s,%s]' % (i, t))

    # Breaks
    # ------
    for i in data.I:
        for t in data.T:
            m.addCons(0 <= cr[i, t], name='Breaks_1_lb[%s,%s]' % (i, t))

    for i in data.I:
        for t in data.T:
            m.addCons(cr[i, t] <= data.WP[i],
                      name='Breaks_1_ub[%s,%s]' % (i, t))

    for i in data.I:
        for t in data.T:
            m.addCons(r[i, t] <= sum([
                er[i, t1]
                for t1 in data.T_int.get_names(p_min=t,
                                               p_max=t + data.RP[i] - 1)
            ]),
                      name='Breaks_2[%s,%s]' % (i, t))

    for i in data.I:
        for t in data.T:
            m.addCons(
                sum([
                    r[i, t1]
                    for t1 in data.T_int.get_names(p_min=t - data.RP[i] + 1,
                                                   p_max=t)
                ]) >= data.RP[i] * er[i, t] if t >= data.min_t - 1 + data.RP[i]
                else data.CRP[i] * s[i, data.min_t] +
                sum([r[i, t1]
                     for t1 in data.T_int.get_names(p_max=t)]) >= data.RP[i] *
                er[i, t],
                name='Breaks_3[%s,%s]' % (i, t))

    for i in data.I:
        for t in data.T:
            m.addCons(sum([
                r[i, t1] + tr[i, t1]
                for t1 in data.T_int.get_names(p_min=t - data.TRP[i],
                                               p_max=t + data.TRP[i])
            ]) >= len(
                data.T_int.get_names(p_min=t - data.TRP[i],
                                     p_max=t + data.TRP[i])) * r[i, t],
                      name='Breaks_4[%s,%s]' % (i, t))

    # Maximum Number of Usage Periods in a Day
    # ----------------------------------------
    for i in data.I:
        m.addCons(sum([u[i, t] for t in data.T]) <= data.UP[i] - data.CUP[i],
                  name='max_usage_periods[%s]' % i)

    # Non-Negligence of Fronts
    # ------------------------
    for g in data.G:
        for t in data.T:
            m.addCons(sum([w[i, t] for i in data.Ig[g]]) >=
                      data.nMin[g, t] * y[t - 1] - mu[g, t],
                      name='non-negligence_1[%s,%s]' % (g, t))

    for g in data.G:
        for t in data.T:
            m.addCons(sum([w[i, t]
                           for i in data.Ig[g]]) <= data.nMax[g, t] * y[t - 1],
                      name='non-negligence_2[%s,%s]' % (g, t))

    # Logical constraints
    # ------------------------
    for i in data.I:
        m.addCons(sum([t * e[i, t]
                       for t in data.T]) >= sum([t * s[i, t] for t in data.T]),
                  name='logical_1[%s]' % i)

    for i in data.I:
        m.addCons(sum([e[i, t] for t in data.T]) <= 1,
                  name='logical_2[%s]' % i)

    for i in data.I:
        for t in data.T:
            m.addCons(r[i, t] + tr[i, t] <= u[i, t],
                      name='logical_3[%s,%s]' % (i, t))

    for i in data.I:
        m.addCons(sum([w[i, t] for t in data.T]) >= z[i],
                  name='logical_4[%s]' % i)

    return solution.Solution(
        m, dict(s=s, tr=tr, r=r, er=er, e=e, u=u, w=w, z=z, cr=cr, y=y, mu=mu))