Exemplo n.º 1
1
    def K_dominance_check(self, _V_best_d, Q_d):
        """
        :param _V_best_d: a list of d-dimension
        :param Q_d: a list of d-dimension
        :return: True if _V_best_d is prefered to Q_d regarding self.Lambda_inequalities and using Kdominance
         other wise it returns False
        """
        _d = len(_V_best_d)

        prob = LpProblem("Ldominance", LpMinimize)
        lambda_variables = LpVariable.dicts("l", range(_d), 0)

        for inequ in self.Lambda_ineqalities:
            prob += lpSum([inequ[j + 1] * lambda_variables[j] for j in range(0, _d)]) + inequ[0] >= 0

        prob += lpSum([lambda_variables[i] * (_V_best_d[i]-Q_d[i]) for i in range(_d)])

        #prob.writeLP("show-Ldominance.lp")

        status = prob.solve()
        LpStatus[status]
        result = value(prob.objective)

        if result < 0:
            return False

        return True
Exemplo n.º 2
0
 def __init__(self):
     self._choices = LpVariable.dicts(
         "Choice", (self.VALUES, self.ROWS, self.COLUMNS), cat='Binary')
     self._values = LpVariable.dicts("Values", (self.ROWS, self.COLUMNS),
                                     min(self.ALL),
                                     max(self.ALL),
                                     cat='Integer')
Exemplo n.º 3
0
    def __load_data_simple(self):
        # There must be at least 9 teams to perform the assigment
        if len(self.teams) < 9:
            raise Exception(ERROR_MIN_TEAM_NOT_FULLFILLED)
        # The number of teams must be dividable by 3
        if len(self.teams) % 3:
            raise Exception(ERROR_NOT_DIVIDABLE_BY_THREE)

        self.groups = [g for g in range(len(self.teams) // 3)]
        self.happiness = {}
        self.distance = {}

        for t in self.teams:
            self.happiness[t] = [0, 0, 0]
            self.happiness[t][t.preferred_course] = 1
            self.happiness[t][t.disliked_course] = -1
        # binary Decision Variables
        self.assign = LpVariable.dicts("Assign team t to group g for course ",
                                       (COURSES, self.teams, self.groups), 0,
                                       1, LpBinary)
        self.chef = LpVariable.dicts("Make team t chef of group g for course ",
                                     (COURSES, self.teams, self.groups), 0, 1,
                                     LpBinary)
        # add equations to model
        self._objective_simple()
        self._team_to_group_per_course()
        self._teams_in_group_per_course()
        self._teams_only_once_in_same_group()
        self._team_as_chef_per_course()
        self._teams_as_chef_in_group()
        self._teams_as_chef_once()
        self._teams_as_chef_only_in_group()
Exemplo n.º 4
0
def formulate(cp):

    prob = dippy.DipProblem("Coke",
                            display_mode = 'xdot',
#                           layout = 'bak',
                            display_interval = None,
                            )

    # create variables
    LOC_SIZES = [(l, s) for l in cp.LOCATIONS
                        for s in cp.SIZES]
    buildVars = LpVariable.dicts("Build", LOC_SIZES, cat=LpBinary)

    # create arcs
    flowVars = LpVariable.dicts("Arcs", cp.ARCS)
    BIG_M = max(sum(cp.supply.values()), sum(cp.demand.values()))
    for a in cp.ARCS:
        flowVars[a].bounds(0, BIG_M)

    # objective
    prob += 1e6 * lpSum(buildVars[(l, s)] * cp.build_costs[s] \
                        for (l, s) in LOC_SIZES) + \
                  lpSum(flowVars[(s, d)] * cp.transport_costs[(s, d)] \
                        for (s, d) in cp.ARCS), "min"

    # plant availability - assumes that SIZES are numeric,
    # which they should be
    for loc in cp.LOCATIONS:
        prob += lpSum(flowVars[(loc, i)] for i in cp.CUSTOMERS) \
             <= lpSum(buildVars[(loc, s)] * s for s in cp.SIZES)

    # one size
    for loc in cp.LOCATIONS:
        prob += lpSum(buildVars[(loc, s)] for s in cp.SIZES) == 1

    # conserve flow (mines)
    # flows are in terms of tonnes of coke
    for m in cp.MINES:
        prob += lpSum(flowVars[(m, j)] for j in cp.LOCATIONS) \
             <= cp.supply[m]

    # conserve flow (locations)
    # convert from coal to coke
    for loc in cp.LOCATIONS:
        prob += lpSum(flowVars[(m, loc)] for m in cp.MINES) - \
                cp.conversion_factor * \
                lpSum(flowVars[(loc, c)] for c in cp.CUSTOMERS) \
             >= 0

    for c in cp.CUSTOMERS:
        prob += lpSum(flowVars[(loc, c)] for loc in cp.LOCATIONS) \
             >= cp.demand[c]

    prob.cp = cp
    prob.buildVars = buildVars
    prob.flowVars = flowVars
    
    return prob
Exemplo n.º 5
0
def formulate(cp):

    prob = dippy.DipProblem(
        "Coke",
        display_mode='xdot',
        #                           layout = 'bak',
        display_interval=None,
    )

    # create variables
    LOC_SIZES = [(l, s) for l in cp.LOCATIONS for s in cp.SIZES]
    buildVars = LpVariable.dicts("Build", LOC_SIZES, cat=LpBinary)

    # create arcs
    flowVars = LpVariable.dicts("Arcs", cp.ARCS)
    BIG_M = max(sum(cp.supply.values()), sum(cp.demand.values()))
    for a in cp.ARCS:
        flowVars[a].bounds(0, BIG_M)

    # objective
    prob += 1e6 * lpSum(buildVars[(l, s)] * cp.build_costs[s] \
                        for (l, s) in LOC_SIZES) + \
                  lpSum(flowVars[(s, d)] * cp.transport_costs[(s, d)] \
                        for (s, d) in cp.ARCS), "min"

    # plant availability - assumes that SIZES are numeric,
    # which they should be
    for loc in cp.LOCATIONS:
        prob += lpSum(flowVars[(loc, i)] for i in cp.CUSTOMERS) \
             <= lpSum(buildVars[(loc, s)] * s for s in cp.SIZES)

    # one size
    for loc in cp.LOCATIONS:
        prob += lpSum(buildVars[(loc, s)] for s in cp.SIZES) == 1

    # conserve flow (mines)
    # flows are in terms of tonnes of coke
    for m in cp.MINES:
        prob += lpSum(flowVars[(m, j)] for j in cp.LOCATIONS) \
             <= cp.supply[m]

    # conserve flow (locations)
    # convert from coal to coke
    for loc in cp.LOCATIONS:
        prob += lpSum(flowVars[(m, loc)] for m in cp.MINES) - \
                cp.conversion_factor * \
                lpSum(flowVars[(loc, c)] for c in cp.CUSTOMERS) \
             >= 0

    for c in cp.CUSTOMERS:
        prob += lpSum(flowVars[(loc, c)] for loc in cp.LOCATIONS) \
             >= cp.demand[c]

    prob.cp = cp
    prob.buildVars = buildVars
    prob.flowVars = flowVars

    return prob
Exemplo n.º 6
0
 def load(self, df):
     self.df = df
     self.players = LpVariable.dicts("p", (player for player in df.index),
                                     cat="Binary")
     teams = df.team.unique()
     self.stack = LpVariable.dicts("v", (team for team in teams),
                                   cat="Binary")
     self.teams = LpVariable.dicts("t", (team for team in teams),
                                   cat="Binary")
Exemplo n.º 7
0
def optimize_set_coverage(OD, existing_facilities=None):

    ### Function for identifying spatially optimal locations of facilities ###
    # REQUIRED:   OD - an Origin:Destination matrix, origins as rows, destinations
    #             as columns, in pandas DataFrame format.
    #             facilities - the 'destinations' of the OD-Matrix.
    #             MUST be a list of objects included in OD.columns (or subset)
    #             if certain nodes are unsuitable for facility locations
    # OPTIONAL:   existing_facilities - facilities to always include in the
    #             solution. MUST be in 'facilities' list
    # -------------------------------------------------------------------------#

    from pulp import LpInteger, LpVariable, LpProblem, lpSum, LpMinimize
    import pandas

    origins = OD.index
    origins = list(map(int, origins))

    facilities = OD.keys()
    facilities = list(map(int, facilities))

    X = LpVariable.dicts('X', (facilities), 0, 1, LpInteger)

    Y = LpVariable.dicts('Y', (origins, facilities), 0, 1, LpInteger)

    #create a binary variable to state that a facility is placed
    #s = LpVariable.dicts('facility', facilities, lowBound=0,upBound=1,cat=LpInteger)

    prob = LpProblem('Set Cover', LpMinimize)

    #prob += sum(sum(OD.loc[i,j] * Y[i][j] for j in facilities) for i in origins)
    prob += sum(X[j] for j in facilities)

    #for i in origins: prob += sum(Y[i][j] for j in facilities) >= 1

    #find a way to calculate percent coverage

    for i in origins:
        #set of facilities that are eligible to provide coverage to point i
        eligibleFacilities = []
        for j in facilities:
            if OD.loc[i, j] <= 240:
                eligibleFacilities.append(j)
        prob += sum(X[j] for j in eligibleFacilities) >= 1

    prob.solve()

    ans = []

    for v in prob.variables():
        subV = v.name.split('_')

        if subV[0] == "X" and v.varValue == 1:
            ans.append(int(str(v).split('_')[1]))

    return ans
Exemplo n.º 8
0
def get_optimal(X, y):
    K, d = X.shape
    names = [str(i) for i in range(K)]
    prob = LpProblem("The Whiskas Problem", LpMinimize)
    w = LpVariable.dicts("w", names)
    abs_w = LpVariable.dicts("abs_w", names, lowBound=0)
    prob += lpSum([abs_w[i] for i in names])
    for j in range(d):
        prob += (lpSum([X[int(i), j] * w[i] for i in names]) == y[j])
    for i in names:
        prob += (abs_w[i] >= w[i])
        prob += (abs_w[i] >= -w[i])
    prob.solve()
    ratio = np.array([abs_w[i].value() for i in names])
    return ratio
Exemplo n.º 9
0
 def __init__(self, costs, sigmas, thetas, alphas, bethas):
     self.prob = LpProblem("AsignacionPacientes", LpMinimize)
     self.A = LpVariable.dicts(
         "A", (ct.citiesIndex, ct.citiesIndex, ct.daysIndex), 0, None,
         LpInteger)
     self.D = LpVariable.dicts("D", (ct.citiesIndex, ct.daysIndex), 0, None,
                               LpInteger)
     self.H = LpVariable.dicts("H", (ct.citiesIndex, ct.daysIndex), 0, None,
                               LpInteger)
     self.costs = costs
     self.sigmas = sigmas
     self.thetas = thetas
     self.alphas = alphas
     self.bethas = bethas
     self.outMatrix = np.zeros((ct.citiesLength, ct.citiesLength))
Exemplo n.º 10
0
def formulate(bpp):
    prob = dippy.DipProblem(
        "Bin Packing",
        display_mode='off',
        #                           layout = 'bak',
        display_interval=None,
    )

    assign_vars = LpVariable.dicts("x", [(i, j) for i in bpp.BINS
                                         for j in bpp.ITEMS],
                                   cat=LpBinary)
    use_vars = LpVariable.dicts("y", bpp.BINS, cat=LpBinary)
    waste_vars = LpVariable.dicts("w", bpp.BINS, 0, None)

    prob += lpSum(waste_vars[i] for i in bpp.BINS), "min_waste"

    for j in bpp.ITEMS:
        prob += lpSum(assign_vars[i, j] for i in bpp.BINS) == 1

    for i in bpp.BINS:
        prob.relaxation[i] += (lpSum(bpp.volume[j] * assign_vars[i, j]
                                     for j in bpp.ITEMS) +
                               waste_vars[i] == bpp.capacity * use_vars[i])

    for i in bpp.BINS:
        for j in bpp.ITEMS:
            prob.relaxation[i] += assign_vars[i, j] <= use_vars[i]

    if Bin_antisymmetry:
        for m in range(0, len(bpp.BINS) - 1):
            prob += use_vars[bpp.BINS[m]] >= use_vars[bpp.BINS[m + 1]]

    if Item_antisymmetry:
        for m in range(0, len(bpp.BINS)):
            for n in range(0, len(bpp.ITEMS)):
                if m > n:
                    i = bpp.BINS[m]
                    j = bpp.ITEMS[n]
                    prob += assign_vars[i, j] == 0

    # Attach the problem data and variable dictionaries
    # to the DipProblem
    prob.bpp = bpp
    prob.assign_vars = assign_vars
    prob.use_vars = use_vars
    prob.waste_vars = waste_vars

    return prob
Exemplo n.º 11
0
def formulate(bpp):
    prob = dippy.DipProblem("Bin Packing",
                            display_mode = 'xdot',
#                           layout = 'bak',
                            display_interval = None,
                            )

    assign_vars = LpVariable.dicts("x",
                                   [(i, j) for i in bpp.BINS
                                    for j in bpp.ITEMS],
                                   cat=LpBinary)
    use_vars    = LpVariable.dicts("y", bpp.BINS, cat=LpBinary)
    waste_vars  = LpVariable.dicts("w", bpp.BINS, 0, None)

    prob += lpSum(waste_vars[i] for i in bpp.BINS), "min_waste"

    for j in bpp.ITEMS:
        prob += lpSum(assign_vars[i, j] for i in bpp.BINS) == 1

    for i in bpp.BINS:
        prob.relaxation[i] += (lpSum(bpp.volume[j] * assign_vars[i, j]
                                for j in bpp.ITEMS) + waste_vars[i] 
                                == bpp.capacity * use_vars[i])

    for i in bpp.BINS:
        for j in bpp.ITEMS:
            prob.relaxation[i] += assign_vars[i, j] <= use_vars[i]

    if Bin_antisymmetry:
        for m in range(0, len(bpp.BINS) - 1):
            prob += use_vars[bpp.BINS[m]] >= use_vars[bpp.BINS[m + 1]]

    if Item_antisymmetry:
        for m in range(0, len(bpp.BINS)):
            for n in range(0, len(bpp.ITEMS)):
                if m > n:
                    i = bpp.BINS[m]
                    j = bpp.ITEMS[n]
                    prob += assign_vars[i, j] == 0

    # Attach the problem data and variable dictionaries
    # to the DipProblem 
    prob.bpp         = bpp
    prob.assign_vars = assign_vars
    prob.use_vars    = use_vars
    prob.waste_vars  = waste_vars

    return prob
Exemplo n.º 12
0
    def K_dominnace_check_2(self, u_d, v_d, _inequalities):
        """

        :param u_d: a d-dimensional vector(list) like [ 8.53149891  3.36436796]
        :param v_d: tha same list like u_d
        :param _inequalities: list of constraints on d-dimensional Lambda Polytope like
         [[0, 1, 0], [1, -1, 0], [0, 0, 1], [1, 0, -1], [0.0, 1.4770889, -3.1250839]]
        :return: True if u is Kdominance to v regarding given _inequalities otherwise False
        """
        _d = len(u_d)

        prob = LpProblem("Kdominance", LpMinimize)
        lambda_variables = LpVariable.dicts("l", range(_d), 0)

        for inequ in _inequalities:
            prob += lpSum([inequ[j + 1] * lambda_variables[j] for j in range(0, _d)]) + inequ[0] >= 0

        prob += lpSum([lambda_variables[i] * (u_d[i]-v_d[i]) for i in range(_d)])

        #prob.writeLP("show-Ldominance.lp")

        status = prob.solve()
        LpStatus[status]

        result = value(prob.objective)
        if result < 0:
            return False

        return True
Exemplo n.º 13
0
def knapsack(w, wi, vi):
    itens = list(sorted(vi.keys()))

    # modelo
    modelo = LpProblem("Knapsack", LpMaximize)

    # variaveis
    x = LpVariable.dicts('x', itens, lowBound=0, upBound=1, cat=LpInteger)

    # objetivo
    modelo += sum(vi[i] * x[i] for i in itens)

    # constantes
    modelo += sum(wi[i] * x[i] for i in itens) <= w

    # otimizacao
    modelo.solve()

    # status
    status = LpStatus[modelo.status]

    respostas = []
    for i in itens:
        respostas.append("{0} = {1}".format(x[i].name.split('_')[1],
                                            int(x[i].varValue)))
    return status, respostas
Exemplo n.º 14
0
def solve_starting_11_problem(selected_team_df):
    """
    Use PuLP to select the starting 11 which maximises next fixture points subject to constraints.

    :param selected_team_df: DataFrame of players in selected team
    :return: List of starting 11 players
    """
    selected_team = selected_team_df.copy()

    players = list(selected_team['name'])

    # CREATE NAME-VALUE DICTIONARIES FOR USE IN CONSTRAINTS

    predictions = dict(zip(selected_team['name'], selected_team['GW_plus_1']))

    DEF_flag = dict(zip(selected_team['name'], selected_team['position_DEF']))

    FWD_flag = dict(zip(selected_team['name'], selected_team['position_FWD']))

    GK_flag = dict(zip(selected_team['name'], selected_team['position_GK']))

    MID_flag = dict(zip(selected_team['name'], selected_team['position_MID']))

    # SET OBJECTIVE FUNCTION

    prob = LpProblem('FPL team selection', LpMaximize)
    player_vars = LpVariable.dicts('player', players, 0, 1, LpInteger)

    prob += lpSum([predictions[p] * player_vars[p]
                   for p in players]), "Total predicted points"

    # DEFINE CONSTRAINTS

    # Rules of the game constraints:

    prob += lpSum(player_vars[p] for p in players) == 11, "Select 11 players"

    prob += lpSum(DEF_flag[p] * player_vars[p]
                  for p in players) >= 3, "At least 3 defenders"

    prob += lpSum(GK_flag[p] * player_vars[p]
                  for p in players) == 1, "1 goalkeeper"

    prob += lpSum(FWD_flag[p] * player_vars[p]
                  for p in players) >= 1, "At least 1 forward"

    # SOLVE OBJECTIVE FUNCTION SUBJECT TO CONSTRAINTS

    prob.solve()
    assert prob.status == 1, 'FPL team selection problem not solved!'

    # Return list of chosen player names:
    chosen_players = []
    for v in prob.variables():
        if v.varValue == 0:
            continue
        else:
            chosen_players.append(v.name.replace('player_', ''))

    return chosen_players
Exemplo n.º 15
0
 def _CreateLinearProblem(self):
     """
         Generates a linear problem object (using PuLP) with all the mass
         balance constraints (Sv = 0), and with individual upper and lower
         bounds on reactions (as given by the model)
     """
     lp = LpProblem("FBA", LpMaximize)
     
     # create the flux variables
     fluxes = LpVariable.dicts("v", self.reactions,
                               lowBound=-1000, upBound=1000)
                          
     for d in self.model['reactions']:
         if d['id'] not in self.reactions:
             print d['id'], "is not found in the list of reactions"
         fluxes[d['id']].lowBound = d['lower_bound']
         fluxes[d['id']].upBound = d['upper_bound']
 
     # add the mass balance constraints for all metabolites
     mass_balance_constraints = {}
     for met in self.metabolites:
         row = self.S.loc[met, :]
         mul = [row[i] * fluxes[self.reactions[i]] for i in row.nonzero()[0]]
         mass_balance_constraints[met] = (lpSum(mul) == 0)
         lp += mass_balance_constraints[met], "mass_balance_%s" % met
     
     return lp, fluxes, mass_balance_constraints
Exemplo n.º 16
0
def getTechnicalEfficiency(r):

    # Model Building
    model = LpProblem('VRS_model', LpMinimize)  # 建立一個新的model,命名為model

    # Decision variables Building
    theta_r = LpVariable(f'theta_r')
    lambda_k = LpVariable.dicts(f'lambda_k', lowBound=0, indexs=K)

    # Objective Function setting
    model += theta_r

    # Constraints setting
    for i in I:
        model += lpSum([lambda_k[k] * X[i][k]
                        for k in K]) <= theta_r * float(X[i][K[r]])
    for j in J:
        model += lpSum([lambda_k[k] * Y[j][k] for k in K]) >= float(Y[j][K[r]])
    model += lpSum([lambda_k[k] for k in K]) == 1

    # model solving
    model.solve()

    return f'{K[r]}:{round(value(model.objective), 3)}\n', value(
        model.objective)
Exemplo n.º 17
0
def create_linear_objective_min_calorie(variables,
                                        prod_values):  #testobjective
    """
    Function returns linear objective to be minimized.
    :param variables: dictionary containing names and LpVariables
    :param prod_values: dictionary of dictionaries containing name and nutrients values
    :return: linear objective to be minimized
    """
    # Student implementation below.
    products_names = list(prod_values.keys())
    nutrients = ['calorie', 'proteins', 'carbs', 'sugar', 'fat']
    prob = LpProblem('Diet problem', LpMinimize)
    calories = []
    proteins = []
    carbs = []
    sugar = []
    fat = []
    for i in range(10):
        tmp = prod_values[products_names[i]]
        calories.append(tmp['calorie'])
        proteins.append(tmp['proteins'])
        carbs.append(tmp['carbs'])
        sugar.append(tmp['sugar'])
        fat.append(tmp['fat'])
    calories = list_to_dict(products_names, calories)
    proteins = list_to_dict(products_names, proteins)
    carbs = list_to_dict(products_names, carbs)
    sugar = list_to_dict(products_names, sugar)
    fat = list_to_dict(products_names, fat)
    food_vars = LpVariable.dicts("Food", products_names, lowBound=0)
    prob += lpSum([calories[i] * variables[i] for i in products_names])
    return LpAffineExpression(prob)
    raise NotImplementedError()
Exemplo n.º 18
0
def solve(n, p):
    prob = LpProblem("routage", LpMaximize)
    matrix = LpVariable.dicts("Matrix", (range(n), range(p)), 0, 1, LpInteger)
    for i in range(n - 1):
        prob += lpSum(matrix[i][j]
                      for j in range(p)) == lpSum(matrix[i + 1][j]
                                                  for j in range(p))
    for j in range(p - 1):
        prob += lpSum(matrix[i][j]
                      for i in range(n)) == lpSum(matrix[i][j + 1]
                                                  for i in range(n))

    res = zeros((n + 1, p + 1), dtype=int)
    while True:
        prob.solve()
        if prob.status == 1:
            nl = int(sum([value(matrix[0][j]) for j in range(p)]))
            nc = int(sum([value(matrix[i][0]) for i in range(n)]))
            res[nc, nl] += 1
            prob += lpSum(
                matrix[i][j] for i in range(n)
                for j in range(p) if value(matrix[i][j]) == 1) + lpSum(
                    1 - matrix[i][j] for i in range(n)
                    for j in range(p) if value(matrix[i][j]) == 0) <= n * p - 1
        else:
            break
    return res
Exemplo n.º 19
0
 def _load_data_simple(self):
     # There must be at least 9 teams to perform the assigment
     if len(self.teams) < 9:
         raise ValidationError(ERROR_MIN_TEAM_NOT_FULLFILLED)
     # The number of teams must be dividable by 3
     if len(self.teams) % 3:
         raise ValidationError(ERROR_NOT_DIVIDABLE_BY_THREE)
     self.COURSES = [
         Course.objects.get(name="a"),
         Course.objects.get(name="m"),
         Course.objects.get(name="d"),
     ]
     self.event = None
     self.groups = [g for g in range(len(self.teams) / 3)]
     self.happiness = {}
     self.distance = {}
     # Sets
     for t in self.teams:
         # check if all teams are from the same event
         if self.event:
             if self.event != t.event:
                 raise ValidationError(ERROR_MULTIPLE_EVENTS)
         else:
             self.event = t.event
         self.happiness[t] = {}
         for c in self.COURSES:
             self.happiness[t][c] = 0
         for l in t.like.all():
             self.happiness[t][l] = 1
         for d in t.dislike.all():
             self.happiness[t][d] = -1
     # binary Decision Variables
     self.assign = LpVariable.dicts("Assign team t to group g for course ",
                                    (self.COURSES, self.teams, self.groups),
                                    0, 1, LpBinary)
     self.chef = LpVariable.dicts("Make team t chef of group g for course ",
                                  (self.COURSES, self.teams, self.groups),
                                  0, 1, LpBinary)
     # add equations to model
     self._objective_simple()
     self._team_to_group_per_course()
     self._teams_in_group_per_course()
     self._teams_only_once_in_same_group()
     self._team_as_chef_per_course()
     self._teams_as_chef_in_group()
     self._teams_as_chef_once()
     self._teams_as_chef_only_in_group()
Exemplo n.º 20
0
def Solver():
    
    global  x,y

    prob = dippy.DipProblem("CVPMP", display_mode = display_mode,
                            layout = 'dot', display_interval = 0)
    
    X = [(i, j) for i in V for j in V]
    x = LpVariable.dicts("x", X, 0, 1, LpBinary)
    y = LpVariable.dicts("y", V, 0, 1, LpBinary)

    prob += (lpSum(d[i, j] * x[(i, j)] for i in V for j in V), "min")
    
    #linking constraints
    for j in V:
        prob += lpSum(x[(i,j)] for i in V) == 1
    
    #non-relaxing
    for i in V:
        prob.relaxation[i] += lpSum(w[j] * x[(i, j)]
                                    for j in V) <= s[i]*y[i]

    prob += lpSum(y[i] for i in V) == p

    prob.relaxed_solver = solve_subproblem

    dippy.Solve(prob, {
        'TolZero'           : '%s' % tol,
        'doCut'        : '1',
        'generateInitVars'  : '1',
        'CutCGL'            : '1',
    })


    #Make solution
    solution = []
    for i in V:
        if y[i].varValue:
            cluster = []
            for j in V:
                if x[(i, j)].varValue:
                    cluster.append(j)

            solution.append((i,cluster))


    return round(prob.objective.value()), solution
Exemplo n.º 21
0
    def solve(self, max_menu_item=None, max_food_item=3, nutrition=DEFAULT_NUTR_REQS, exclude=None, include=None):
        """Create, formulate and solve the diet problem for given constraints
        """
        self.prob = prob = LpProblem(__class__, LpMinimize)

        # Variables
        self.xm = xm = LpVariable.dicts('meals', self.meals, 0, max_menu_item, cat='Integer')
        self.xf = xf = LpVariable.dicts('foods', self.foods, 0, max_food_item, cat='Integer')

        # Objective
        prob += lpSum(self.menu[i]['price']*xm[i] for i in self.meals)

        # Ensure that foods eaten are available under meals bought
        for j in self.foods:
            prob += lpSum([self.menu[i]['foods'].get(j, 0)*xm[i] for i in self.meals]) >= xf[j]

        # Must meet nutrition
        for r, (lower, upper) in nutrition.items():
            if lower:
                prob += lpSum([xf[i]*self.nutr[i][r] for i in self.foods]) >= lower
            if upper:
                prob += lpSum([xf[i]*self.nutr[i][r] for i in self.foods]) <= upper

        if include:
            for food in include:
                prob += xf[food] >= 1

        if exclude:
            for food in exclude:
                prob += xf[food] == 0

        # Solve and save
        status = LpStatus[prob.solve()]
        if status == 'Optimal':
            pass
        elif status == 'Infeasible':
            raise InfeasibleError()
        elif status == 'Unbounded':
            raise UnboundedError
        else:
            raise ValueError(status)

        solution = self.parse_solution()
        self.history.append(solution)
        return solution
Exemplo n.º 22
0
def formulate(bpp, args):

    prob = DipProblem("Bin Packing")

    assign_vars = LpVariable.dicts("x", [(i, j) for i in bpp.BINS
                                         for j in bpp.ITEMS],
                                   cat=LpBinary)
    use_vars = LpVariable.dicts("y", bpp.BINS, cat=LpBinary)
    waste_vars = LpVariable.dicts("w", bpp.BINS, 0, None)

    prob += lpSum(waste_vars[i] for i in bpp.BINS), "min_waste"

    for j in bpp.ITEMS:
        prob += lpSum(assign_vars[i, j] for i in bpp.BINS) == 1

    for i in bpp.BINS:
        prob.relaxation[i] += (lpSum(bpp.volume[j] * assign_vars[i, j]
                                     for j in bpp.ITEMS) +
                               waste_vars[i] == bpp.capacity * use_vars[i])

    for i in bpp.BINS:
        for j in bpp.ITEMS:
            prob.relaxation[i] += assign_vars[i, j] <= use_vars[i]

    if args.antisymmetryCutsBins:
        for m in range(0, len(bpp.BINS) - 1):
            prob += use_vars[bpp.BINS[m]] >= use_vars[bpp.BINS[m + 1]]

    if args.antisymmetryCutsItems:
        for m in range(0, len(bpp.BINS)):
            for n in range(0, len(bpp.ITEMS)):
                if m > n:
                    i = bpp.BINS[m]
                    j = bpp.ITEMS[n]
                    prob += assign_vars[i, j] == 0

    # Attach the problem data and variable dictionaries
    # to the DipProblem
    prob.bpp = bpp
    prob.assign_vars = assign_vars
    prob.use_vars = use_vars
    prob.waste_vars = waste_vars
    prob.tol = pow(pow(2, -24), old_div(2.0, 3.0))

    return prob
Exemplo n.º 23
0
def Solver(args):

    global x, y

    prob = DipProblem("CVPMP",
                      display_mode=display_mode,
                      layout='dot',
                      display_interval=0)

    X = [(i, j) for i in V for j in V]
    x = LpVariable.dicts("x", X, 0, 1, LpBinary)
    y = LpVariable.dicts("y", V, 0, 1, LpBinary)

    prob += (lpSum(d[i, j] * x[(i, j)] for i in V for j in V), "min")

    #linking constraints
    for j in V:
        prob += lpSum(x[(i, j)] for i in V) == 1

    #non-relaxing
    for i in V:
        prob.relaxation[i] += lpSum(w[j] * x[(i, j)] for j in V) <= s[i] * y[i]

    prob += lpSum(y[i] for i in V) == p

    if args.useCustomSolver:
        prob.relaxed_solver = solve_subproblem

    dippyOpts = addDippyOpts(args)

    Solve(prob, dippyOpts)

    #Make solution
    solution = []
    for i in V:
        if y[i].varValue:
            cluster = []
            for j in V:
                if x[(i, j)].varValue:
                    cluster.append(j)

            solution.append((i, cluster))

    return round(prob.objective.value()), solution
Exemplo n.º 24
0
    def _create_variables(self) -> None:
        """Creates the set of variables Y* and X* of the PuLP problem.

        Override it if you need to create extra variables (first use
        ``super().create_variables()`` to call the base class method)."""
        if self.relaxed:
            kind = LpContinuous
        else:
            kind = LpInteger

        # List all combinations of apps and instances and workloads
        comb_res = cartesian_product(self.system.apps,
                                     self.cooked.instances_res)
        comb_dem = cartesian_product(self.system.apps,
                                     self.cooked.instances_dem,
                                     self.load_hist.keys())
        map_res = LpVariable.dicts("Y", comb_res, 0, None, kind)
        map_dem = LpVariable.dicts("X", comb_dem, 0, None, kind)
        self.cooked = self.cooked._replace(map_res=map_res, map_dem=map_dem)
Exemplo n.º 25
0
 def setup_vars(self, idx):
     """Create a dictionary with the pulp variables."""
     return {
         'imports':
         LpVariable.dicts('import',
                          idx[:-1],
                          lowBound=0,
                          upBound=self.power,
                          cat='Continuous'),
         'exports':
         LpVariable.dicts('export',
                          idx[:-1],
                          lowBound=0,
                          upBound=self.power,
                          cat='Continuous'),
         'charges':
         LpVariable.dicts('charge', idx, lowBound=0, cat='Continuous'),
         'losses':
         LpVariable.dicts('loss', idx[:-1], lowBound=0, cat='Continuous')
     }
Exemplo n.º 26
0
def solve_under_coverage(graph, min_coverage=80):

    prob = LpProblem("granularity selection", LpMinimize)
    codelet_vars = LpVariable.dicts("codelet",
                                    graph,
                                    lowBound=0,
                                    upBound=1,
                                    cat=LpInteger)

    # Objective function: minimize the total replay cost of selected codelets

    # Compute replay time
    for n, d in graph.nodes(data=True):
        d['_total_replay_cycles'] = 0
        for inv in d['_invocations']:
            d['_total_replay_cycles'] = d['_total_replay_cycles'] + float(
                inv["Invivo (cycles)"])

    prob += lpSum([
        codelet_vars[n] * d['_total_replay_cycles']
        for n, d in graph.nodes(data=True)
    ])

    # and with good coverage
    prob += (lpSum(
        [codelet_vars[n] * d['_coverage']
         for n, d in graph.nodes(data=True)]) >= min_coverage)

    # selected codelets should match
    for n, d in graph.nodes(data=True):
        if not d['_matching']:
            prob += codelet_vars[n] == 0

    # Finally we should never include both the children and the parents
    for dad in graph.nodes():
        for son in graph.nodes():
            if not dad in nx.ancestors(graph, son):
                continue
            # We cannot select dad and son at the same time
            prob += codelet_vars[dad] + codelet_vars[son] <= 1

    #prob.solve(GLPK())
    prob.solve()
    if (LpStatus[prob.status] != 'Optimal'):
        raise Unsolvable()

    for v in prob.variables():
        assert v.varValue == 1.0 or v.varValue == 0.0
        if v.varValue == 1.0:

            for n, d in graph.nodes(data=True):
                if ("codelet_" + str(n)) == v.name:
                    d["_selected"] = True
                    yield n
Exemplo n.º 27
0
 def setup_vars(self, idx):
     """Create a dictionary with the pulp variables."""
     return {
         "imports":
         LpVariable.dicts("import",
                          idx[:-1],
                          lowBound=0,
                          upBound=self.power,
                          cat="Continuous"),
         "exports":
         LpVariable.dicts("export",
                          idx[:-1],
                          lowBound=0,
                          upBound=self.power,
                          cat="Continuous"),
         "charges":
         LpVariable.dicts("charge", idx, lowBound=0, cat="Continuous"),
         "losses":
         LpVariable.dicts("loss", idx[:-1], lowBound=0, cat="Continuous"),
     }
Exemplo n.º 28
0
def knapsack01(obj, weights, capacity):
    """ 0/1 knapsack solver, maximizes profit. weights and capacity integer """
        
    debug_subproblem = False
    
    assert len(obj) == len(weights)
    n = len(obj)
    if n == 0:
        return 0, []

    if debug_subproblem:
        relaxation = LpProblem('relaxation', LpMaximize)
        relax_vars = [str(i) for i in range(n)]
        var_dict   = LpVariable.dicts("", relax_vars, 0, 1, LpBinary)
        relaxation += (lpSum(var_dict[str(i)] * weights[i] for i in range(n)) 
                       <= capacity)
        relaxation += lpSum(var_dict[str(i)] * obj[i] for i in range(n))
        relaxation.solve()
        relax_obj = value(relaxation.objective)

        solution =  [i for i in range(n) if var_dict[str(i)].varValue > tol ]

        print relax_obj, solution


    c = [[0]*(capacity+1) for i in range(n)]
    added = [[False]*(capacity+1) for i in range(n)]
    # c [items, remaining capacity]
    # important: this code assumes strictly positive objective values
    for i in range(n):
        for j in range(capacity+1):
            if (weights[i] > j):
                c[i][j] = c[i-1][j]
            else:
                c_add = obj[i] + c[i-1][j-weights[i]]
                if c_add > c[i-1][j]:
                    c[i][j] = c_add
                    added[i][j] = True
                else:
                    c[i][j] = c[i-1][j]

    # backtrack to find solution
    i = n-1
    j = capacity

    solution = []
    while i >= 0 and j >= 0:
        if added[i][j]:
            solution.append(i)
            j -= weights[i]
        i -= 1
        
    return c[n-1][capacity], solution
Exemplo n.º 29
0
 def VAR_matrix(self,
                rows=10,
                columns=10,
                prefix='x',
                type=LpBinary,
                to_print=False):
     m = LpVariable.dicts(prefix, (range(rows), range(columns)),
                          cat=type,
                          lowBound=0)
     if to_print:
         print(f"VAR_matrix : \n{m} - ({type.lower()})")
     return m
def pe185():
    """
    Modelling as an integer programming problem.
    Then using PuLP to solve it. It's really fast, just 0.24 seconds. 
    For details, see https://pythonhosted.org/PuLP/index.html
    """
    
    from pulp import LpProblem, LpVariable, LpMinimize, LpInteger, lpSum, value

    constraints = [
        ('2321386104303845', 0),
        ('3847439647293047', 1),
        ('3174248439465858', 1),
        ('8157356344118483', 1),
        ('6375711915077050', 1),
        ('6913859173121360', 1),
        ('4895722652190306', 1),
        ('5616185650518293', 2),
        ('4513559094146117', 2),
        ('2615250744386899', 2),
        ('6442889055042768', 2),
        ('2326509471271448', 2),
        ('5251583379644322', 2),
        ('2659862637316867', 2),
        ('5855462940810587', 3),
        ('9742855507068353', 3),
        ('4296849643607543', 3),
        ('7890971548908067', 3),
        ('8690095851526254', 3),
        ('1748270476758276', 3),
        ('3041631117224635', 3),
        ('1841236454324589', 3)
    ]

    VALs = map(str, range(10))
    LOCs = map(str, range(16))
    choices = LpVariable.dicts("Choice", (LOCs, VALs), 0, 1, LpInteger)

    prob = LpProblem("pe185", LpMinimize)
    prob += 0, "Arbitrary Objective Function"

    for s in LOCs:
        prob += lpSum([choices[s][v] for v in VALs]) == 1, ""

    for c, n in constraints:
        prob += lpSum([choices[str(i)][v] for i,v in enumerate(c)]) == n, ""

    prob.writeLP("pe185.lp")
    prob.solve()
    res = int(''.join(v for s in LOCs for v in VALs if value(choices[s][v])))

    # answer: 4640261571849533
    return res
Exemplo n.º 31
0
    def solve_exact(self):
        '''
            整数計画法を用いて厳密解を得る

        parameters
        -----
            なし
        returns
        -----
            なし
        '''
        from pulp import LpProblem, LpVariable, lpSum, LpStatus, PULP_CBC_CMD

        n_city = self.size
        #Pulpで解く
        p = LpProblem("TSP")
        x = LpVariable.dicts(name="x",
                             indexs=(range(n_city), range(n_city)),
                             cat='Binary')

        p += lpSum(
            self.dist(i, j) * x[i][j]
            for i, j in product(range(n_city), range(n_city)))

        for i in range(n_city):
            p += lpSum(x[i][j] for j in range(n_city)) == 1

        for i in range(n_city):
            p += lpSum(x[j][i] for j in range(n_city)) == 1

        V = set(range(n_city))
        for s_len in range(1, n_city - 1):
            for S_list in combinations(range(n_city), s_len):
                S = set(S_list)
                _V = V - S
                tmp = 0
                for i, j in product(S, _V):
                    tmp += x[i][j]
                p += tmp >= 1

        solver = PULP_CBC_CMD(threads=15)
        status = p.solve(solver)
        print(LpStatus[status])

        self.exact_route = [0]
        for i in range(n_city - 1):
            for j in range(n_city):
                if x[self.exact_route[i]][j].value() == 1.0:
                    self.exact_route.append(j)
                    break

        self.exact_dist = self.route_len(self.exact_route)
Exemplo n.º 32
0
    def localPL(self, timeStamp):
        prob = LpProblem("Maximize monads", LpMaximize)
        vars_ = [
            "X" + str(c)
            for c in range(len(self.monads.getMonadsByYear(timeStamp)))
        ]
        vars = LpVariable.dicts("Number of monads", vars_, lowBound=0)
        [
            "X" + str(c)
            for c in range(len(self.monads.getMonadsByYear(timeStamp)))
        ]

        prob += lpSum([rois[c] * vars[c] for c in Chairs])
Exemplo n.º 33
0
def formulate(bpp):
    prob = dippy.DipProblem("Bin Packing",
                            display_mode = 'xdot',
#                           layout = 'bak',
                            display_interval = None,
                            )

    assign_vars = LpVariable.dicts("x",
                                   [(i, j) for i in bpp.ITEMS
                                    for j in bpp.BINS],
                                   cat=LpBinary)
    use_vars    = LpVariable.dicts("y", bpp.BINS, cat=LpBinary)
    waste_vars  = LpVariable.dicts("w", [(j, k) for j in bpp.BINS
                                          for k in bpp.LIMITS], 0, None)

    prob += lpSum(use_vars[j] for j in bpp.BINS), "min_bins"

    for j in bpp.BINS:
      for k in bpp.LIMITS:
        prob += lpSum(bpp.volume[i, k] * assign_vars[i, j] for i in bpp.ITEMS) \
                + waste_vars[j, k] == bpp.capacity[k] * use_vars[j]

    for i in bpp.ITEMS:
        prob += lpSum(assign_vars[i, j] for j in bpp.BINS) == 1

    for i in bpp.ITEMS:
        for j in bpp.BINS:
            prob += assign_vars[i, j] <= use_vars[j]

    for n in range(0, len(bpp.BINS) - 1):
        prob += use_vars[bpp.BINS[n]] >= use_vars[bpp.BINS[n + 1]]

    # Attach the problem data and variable dictionaries to the DipProblem 
    prob.bpp         = bpp
    prob.assign_vars = assign_vars
    prob.use_vars    = use_vars
    prob.waste_vars  = waste_vars

    return prob
Exemplo n.º 34
0
def formulate(bpp):
    prob = dippy.DipProblem(
        "Bin Packing",
        display_mode='xdot',
        #                           layout = 'bak',
        display_interval=None,
    )

    assign_vars = LpVariable.dicts("x", [(i, j) for i in bpp.ITEMS
                                         for j in bpp.BINS],
                                   cat=LpBinary)
    use_vars = LpVariable.dicts("y", bpp.BINS, cat=LpBinary)
    waste_vars = LpVariable.dicts("w", [(j, k) for j in bpp.BINS
                                        for k in bpp.LIMITS], 0, None)

    prob += lpSum(use_vars[j] for j in bpp.BINS), "min_bins"

    for j in bpp.BINS:
        for k in bpp.LIMITS:
            prob += lpSum(bpp.volume[i, k] * assign_vars[i, j] for i in bpp.ITEMS) \
                    + waste_vars[j, k] == bpp.capacity[k] * use_vars[j]

    for i in bpp.ITEMS:
        prob += lpSum(assign_vars[i, j] for j in bpp.BINS) == 1

    for i in bpp.ITEMS:
        for j in bpp.BINS:
            prob += assign_vars[i, j] <= use_vars[j]

    for n in range(0, len(bpp.BINS) - 1):
        prob += use_vars[bpp.BINS[n]] >= use_vars[bpp.BINS[n + 1]]

    # Attach the problem data and variable dictionaries to the DipProblem
    prob.bpp = bpp
    prob.assign_vars = assign_vars
    prob.use_vars = use_vars
    prob.waste_vars = waste_vars

    return prob
Exemplo n.º 35
0
    def solve_pulp(self, start=0, end=4):
        #最小化問題
        p = LpProblem("ShortestPath", sense=LpMinimize)
        #変数
        x = LpVariable.dicts('x', range(len(self.edges)), 0, 1, cat=LpBinary)

        #目的関数
        p += sum([x[i] * self.get_weight(i) for i in range(self.edges_num)])
        #p += sum([ x[i] for i in range(self.edges_num)])

        #制約式
        for i in self.nodes:
            const_out = 0
            tmp_edges = []
            for e in self.G.edges(i):
                j = e[1]
                const_out += x[self.get_node_index((i, j))]
                tmp_edges.append(self.get_node_index((i, j)))
            logging.debug(tmp_edges)

            const_in = 0
            tmp_edges = []
            for e in self.G.in_edges(i):
                k = e[0]
                const_in += x[self.get_node_index((k, i))]
                tmp_edges.append(self.get_node_index((k, i)))
            logging.debug(tmp_edges)

            print(i, self.G.edges(i), self.G.in_edges(i))

            #self.G.edges()
            if i == self.start:
                const_val = 1
            elif i == self.goal:
                const_val = -1
            else:
                const_val = 0

            p += const_out - const_in == const_val

        self.status = p.solve()
        if self.status == 1:
            self.answer = [
                self.edges[i] for i in range(self.edges_num)
                if x[i].value() == 1
            ]
            logging.debug(f"ans {self.answer}")
        else:
            logging.error("Solve Failed")

        print(self.answer)
Exemplo n.º 36
0
    def create_problem(self, filename=None, use_no_fit=False):

        if self.polygons is None:
            raise ValueError('You must create the data before the model!')

        self.use_no_fit = use_no_fit

        self.problem = LpProblem('polygons_packing', LpMinimize)

        self.w = LpVariable('w', 0)

        self.tx = LpVariable.dicts('tx', range(self.N), 0)
        self.ty = LpVariable.dicts('ty', range(self.N), 0)

        # objective
        self.problem.setObjective(self.w)

        # w constraints
        widths = [
            np.max(pol[:, 0]) - np.min(pol[:, 0]) for pol in self.polygons
        ]
        for i in range(self.N):
            self.problem += self.w - self.tx[i] >= widths[
                i], f"w_constraint_{i}"

        # height constraints
        heights = [
            np.max(pol[:, 1]) - np.min(pol[:, 1]) for pol in self.polygons
        ]
        for i in range(self.N):
            self.problem += self.ty[
                i] <= self.H - heights[i], f"height_constraint_{i}"

        self._add_non_overl_constr()

        if filename is not None:
            self.problem.writeLP(filename)
Exemplo n.º 37
0
def solve_under_coverage(graph, min_coverage=80):

    prob = LpProblem("granularity selection", LpMinimize)
    codelet_vars = LpVariable.dicts("codelet",
            graph,
            lowBound=0,
            upBound=1,
            cat=LpInteger)

    # Objective function: minimize the total replay cost of selected codelets

    # Compute replay time
    for n,d in graph.nodes(data=True):
      d['_total_replay_cycles'] = 0
      for inv in d['_invocations']:
        d['_total_replay_cycles'] = d['_total_replay_cycles'] + float(inv["Invivo (cycles)"])

    prob += lpSum([codelet_vars[n]*d['_total_replay_cycles'] for n,d in graph.nodes(data=True)])

    # and with good coverage
    prob += (lpSum([codelet_vars[n]*d['_coverage'] for n,d in graph.nodes(data=True)]) >= min_coverage)

    # selected codelets should match
    for n,d in graph.nodes(data=True):
        if not d['_matching']:
            prob += codelet_vars[n] == 0

    # Finally we should never include both the children and the parents
    for dad in graph.nodes():
        for son in graph.nodes():
            if not dad in nx.ancestors(graph, son):
                continue
            # We cannot select dad and son at the same time
            prob += codelet_vars[dad] + codelet_vars[son] <= 1

    #prob.solve(GLPK())
    prob.solve()
    if (LpStatus[prob.status] != 'Optimal'):
        raise Unsolvable()

    for v in prob.variables():
        assert v.varValue == 1.0 or v.varValue == 0.0
        if v.varValue == 1.0:

            for n,d in graph.nodes(data=True):
                if ("codelet_"+str(n)) == v.name:
                    d["_selected"] = True
                    yield n
Exemplo n.º 38
0
    def _recurse(work_pairs, mae, grace=None):
        req = grace or 1.0

        demands = {
            'morning': mae[0],
            'afternoon': mae[1],
            'exam': mae[2],
        }
        total_avg = float(sum([demands[i] for i in SHIFTS])) / work_pairs
        total_low, total_high = floor(total_avg), ceil(total_avg)
        work_pair_count = work_pairs
        avgs = [float(demands[i]) / work_pair_count for i in SHIFTS]
        lows = [floor(a) for a in avgs]
        highs = [ceil(a) for a in avgs]

        target = req * total_avg * float(sum([COSTS[i] for i in SHIFTS])) / len(SHIFTS)

        prob = LpProblem("Work Distribution", LpMinimize)
        var_prefix = "shift"
        shift_vars = LpVariable.dicts(var_prefix, SHIFTS, 0, cat=LpInteger)
        prob += lpSum([COSTS[i] * shift_vars[i] for i in SHIFTS]), "cost of combination"
        prob += lpSum([COSTS[i] * shift_vars[i] for i in SHIFTS]) >= target, "not too good"
        prob += lpSum([shift_vars[i] for i in SHIFTS]) >= total_low, "low TOTAL"
        prob += lpSum([shift_vars[i] for i in SHIFTS]) <= total_high, "high TOTAL"

        for shift, low, high in zip(SHIFTS, lows, highs):
            prob += lpSum([shift_vars[shift]]) >= low, "low %s" % shift
            prob += lpSum([shift_vars[shift]]) <= high, "high %s" % shift

        prob.solve(GLPK_CMD(msg=0))

        if not LpStatus[prob.status] == 'Optimal':
            next_grace = req - 0.1
            assert 0.0 < next_grace
            return _recurse(work_pairs, mae, next_grace)

        new_mae = [0, 0, 0]
        solution = [0, 0, 0]
        for v in prob.variables():
            for pos, name in enumerate(SHIFTS):
                if v.name == "%s_%s" % (var_prefix, name):
                    solution[pos] = v.varValue
                    new_mae[pos] = mae[pos] - solution[pos]

        return (PairAlloc(solution), work_pairs - 1) + tuple(new_mae)
Exemplo n.º 39
0
def get_optimal_routes(sources, destinations):
    sources = collections.OrderedDict([(x['id'], x) for x in sources])
    destinations = collections.OrderedDict([(x['id'], x) for x in destinations])

    sources_points = [{'lat': x['lat'], 'lng': x['lng']} for x in sources.values()]
    destinations_points = [{'lat': x['lat'], 'lng': x['lng']} for x in destinations.values()]

    source_ids = [str(x['id']) for x in sources.values()]
    dest_ids = [str(x['id']) for x in destinations.values()]

    demand = {str(x['id']): convert_int(x['num_students']) for x in sources.values()}
    supply = {str(x['id']): convert_int(x['num_students']) for x in destinations.values()}

    log.info("Calling gmaps api...")
    distances = gmaps.distance_matrix(origins=sources_points, destinations=destinations_points, mode='walking')

    costs = {}
    for i, origin in enumerate(distances['rows']):
        origin_costs = {}
        for j, entry in enumerate(origin['elements']):
            origin_costs[dest_ids[j]] = entry['duration']['value']
        costs[source_ids[i]] = origin_costs

    prob = LpProblem("Evaucation Routing for Schools",LpMinimize)
    routes = [(s,d) for s in source_ids for d in dest_ids]
    route_lookup = {'Route_{}_{}'.format(x.replace(' ','_'),y.replace(' ','_')):(x,y) for (x,y) in routes}
    route_vars = LpVariable.dicts("Route",(source_ids,dest_ids),0,None,LpInteger)
    prob += lpSum([route_vars[w][b]*(costs[w][b]**2) for (w,b) in routes])
    for dest in dest_ids:
        prob += lpSum([route_vars[source][dest] for source in source_ids]) <= supply[dest], "Students going to {} is <= {}".format(dest, supply[dest])
    for source in source_ids:
        prob += lpSum([route_vars[source][dest] for dest in dest_ids]) == demand[source], "Students leaving {} is {}".format(source, demand[source])

    log.info("Optimizing routes...")
    prob.solve()

    if prob.status != 1:
        raise Exception("Algorithm could not converge to a solution")

    result = []
    for v in prob.variables():
        src, dst = route_lookup[v.name]
        value = v.value()
        result.append({'src': sources[src], 'dst': destinations[dst], 'value': int(value)})
    return result
Exemplo n.º 40
0
    def __init__(self, home_list, work_list, util_matrix):
        """ Input a list of utils
            utils = [   #Works
                    #1 2 3 4 5
                    [2,4,5,2,1],#A   Homes
                    [3,1,3,2,3] #B
                    ]
        """
        self.util_matrix = util_matrix
        self.homes = dict((home, home.houses) for home in home_list)
        self.works = dict((work, work.jobs) for work in work_list)
        self.utils = makeDict([home_list, work_list], util_matrix, 0)

        # Creates the 'prob' variable to contain the problem data
        self.prob = LpProblem("Residential Location Choice Problem", LpMinimize)

        # Creates a list of tuples containing all the possible location choices
        self.choices = [(h, w) for h in self.homes for w in self.works.keys()]

        # A dictionary called 'volumes' is created to contain the referenced variables(the choices)
        self.volumes = LpVariable.dicts("choice", (self.homes, self.works), 0, None, LpContinuous)

        # The objective function is added to 'prob' first
        self.prob += (
            lpSum([self.volumes[h][w] * self.utils[h][w] for (h, w) in self.choices]),
            "Sum_of_Transporting_Costs",
        )

        # The supply maximum constraints are added to prob for each supply node (home)
        for h in self.homes:
            self.prob += (
                lpSum([self.volumes[h][w] for w in self.works]) <= self.homes[h],
                "Sum_of_Products_out_of_Home_%s" % h,
            )

        # The demand minimum constraints are added to prob for each demand node (work)
        for w in self.works:
            self.prob += (
                lpSum([self.volumes[h][w] for h in self.homes]) >= self.works[w],
                "Sum_of_Products_into_Work%s" % w,
            )
Exemplo n.º 41
0
    def __generar_restricciones(self):
        X = LpVariable.dicts('X', self.variables, cat = LpBinary)
        self.cursado = LpProblem("Cursado",LpMaximize)

        # "\n\n Restricciones de dia-modulo\n\n"
        i = 1
        for r in self.r1.values():
            self.cursado += lpSum([X["".join(x)] for x in r]) <= 1, \
            "_1C" + str(i).zfill(3)
            i += 1

        #"\n\n Restricciones de cursado completo\n\n"

        for r in self.r2.values():
            self.cursado += int(r[0][0]) *X[r[0][1]+r[0][2]] == lpSum([X["".join(x[1:])] for x in r]), \
            "_2C" + str(i).zfill(3)
            i += 1
        #"""

        #"\n\n Restricciones 1 sola comision\n\n"
        for r in self.r3.values():
            self.cursado += int(r[0][0]) *X[r[0][1]] == lpSum([X["".join(x[1:])] for x in r]), \
            "_3C" + str(i).zfill(3)
            i += 1

        #"\n\n Restricciones de Colision\n\n"
        for r in self.r4.values():
            self.cursado += lpSum([X["".join(x)] for x in r]) <= 1, \
            "_4C" + str(i).zfill(3)
            i += 1

        #"\n\n Restricciones de franja horaria\n\n"

        for r in [x + "" for x in ["".join(x) for x in self.r5]]:
            self.cursado += X[r] == 0, \
            "_5C" + str(i).zfill(3)
            i += 1

        self.X = X
Exemplo n.º 42
0
def build_sudoku_problem():

    # The values, rows and cols sequences all follow this form
    values = range(9)
    rows = range(9)
    columns = range(9)

    # The boxes list is created, with the row and column index of each square in each box
    boxes = []
    for i in range(3):
        for j in range(3):
            box = [(rows[3 * i + k], columns[3 * j + l]) for k in range(3) for l in range(3)]
            boxes.append(box)

    # The problem variable is created to contain the problem data
    problem = LpProblem("Sudoku Problem", LpMinimize)
    # The problem variables are created
    choices = LpVariable.dicts("Choice", (rows, columns, values), 0, 1, LpBinary)
    # The arbitrary objective function is added
    problem += 0, "Arbitrary Objective Function"

    # A constraint ensuring that only one value can be in each square is created
    for r in rows:
        for c in columns:
            problem += lpSum(choices[r][c][v] for v in values) == 1, "unique_val_" + str(r) + '_' + str(c)

    # The row, column and box constraints are added for each value
    for v in values:
        for r in rows:
            problem += lpSum(choices[r][c][v] for c in columns) == 1, "row_" + str(v) + '_' + str(r)

        for c in columns:
            problem += lpSum(choices[r][c][v] for r in rows) == 1, "col_" + str(v) + '_' + str(c)

        for box_index, b in enumerate(boxes):
            problem += lpSum(choices[r][c][v] for (r, c) in b) == 1, "box_" + str(v) + '_' + str(box_index)

    return problem, choices, values, rows, columns
Exemplo n.º 43
0
	def learn_two_cat(self, performance_table):
		"""Learn parameters for two categories and two training sets of alternatives."""		
		if len(self.categories) != 2:
			raise SemanticError, "The learnTwoCat() method requires exactly two categories."

		prob = LpProblem("twoCat", LpMaximize)

		alts = filter(lambda a: a.__class__.__name__ != "LimitProfile", performance_table.alts)
		crits = self.crits

		alts_name = [alt.name for alt in alts if alt.__class__.__name__ != "LimitProfile"]
		crits_name = [crit.name for crit in crits]

		self.categories.sort(key=lambda c: c.rank)

		alts1 = [alt for alt in alts if alt.category == self.categories[0]]
		alts2 = [alt for alt in alts if alt.category == self.categories[1]]

		#small float number
		epsilon = 0.00001

		#variables (v: variable, d: dict of variables)
		v_lambda = LpVariable("lambda", lowBound=0.5, upBound=1)
		v_alpha = LpVariable("alpha", lowBound=0)
		d_x = LpVariable.dicts("x", alts_name, lowBound=0)
		d_y = LpVariable.dicts("y", alts_name, lowBound=0)
		d_p = LpVariable.dicts("p", crits_name, lowBound=0, upBound=1)
		d_gb = LpVariable.dicts("gb", crits_name, lowBound=0, upBound=1)
		d_delta = LpVariable.dicts("delta", \
			[alt.name + crit.name for alt in alts for crit in crits]\
			, cat=LpBinary)
		d_c = LpVariable.dicts("c", \
			[alt.name + crit.name for alt in alts for crit in crits]\
			, lowBound=0, upBound=1)

		#maximize
		prob += v_alpha

		#constraints
		for alt in alts2:
			prob += sum(d_c[alt.name + crit.name] for crit in crits) + d_x[alt.name] == v_lambda
		for alt in alts1:
			prob += sum(d_c[alt.name + crit.name] for crit in crits) == v_lambda + d_y[alt.name]

		for alt in alts:
			prob += v_alpha <= d_x[alt.name]
			prob += v_alpha <= d_y[alt.name]
			prob += d_x[alt.name] >= epsilon
			
			for crit in crits:
				prob += d_c[alt.name + crit.name] <= d_p[crit.name]
				prob += d_c[alt.name + crit.name] >= d_delta[alt.name + crit.name] + d_p[crit.name] - 1
				prob += d_c[alt.name + crit.name] <= d_delta[alt.name + crit.name]
				prob += d_delta[alt.name + crit.name] >= performance_table[alt][crit] - d_gb[crit.name] + epsilon
				prob += d_delta[alt.name + crit.name] <= performance_table[alt][crit] - d_gb[crit.name] + 1

		prob += sum(d_p[crit.name] for crit in crits) == 1

		#solver
		GLPK().solve(prob)

		#prob.writeLP("SpamClassification.lp")
		#status = prob.solve()


		#update parameters
		self.cutting_threshold = v_lambda.value()

		for crit in crits:
			crit.weight = d_p[crit.name].value()

		for crit in crits:
			performance_table[self.limit_profiles[0]][crit] = d_gb[crit.name].value()
Exemplo n.º 44
0
def BranchAndBound(T, CONSTRAINTS, VARIABLES, OBJ, MAT, RHS,
                   branch_strategy = MOST_FRACTIONAL,
                   search_strategy = DEPTH_FIRST,
                   complete_enumeration = False,
                   display_interval = None,
                   binary_vars = True):
    
    if T.get_layout() == 'dot2tex':
        cluster_attrs = {'name':'Key', 'label':r'\text{Key}', 'fontsize':'12'}
        T.add_node('C', label = r'\text{Candidate}', style = 'filled',
                      color = 'yellow', fillcolor = 'yellow')
        T.add_node('I', label = r'\text{Infeasible}', style = 'filled',
                      color = 'orange', fillcolor = 'orange')
        T.add_node('S', label = r'\text{Solution}', style = 'filled',
                      color = 'lightblue', fillcolor = 'lightblue')
        T.add_node('P', label = r'\text{Pruned}', style = 'filled',
                      color = 'red', fillcolor = 'red')
        T.add_node('PC', label = r'\text{Pruned}$\\ $\text{Candidate}', style = 'filled',
                      color = 'red', fillcolor = 'yellow')
    else:
        cluster_attrs = {'name':'Key', 'label':'Key', 'fontsize':'12'}
        T.add_node('C', label = 'Candidate', style = 'filled',
                      color = 'yellow', fillcolor = 'yellow')
        T.add_node('I', label = 'Infeasible', style = 'filled',
                      color = 'orange', fillcolor = 'orange')
        T.add_node('S', label = 'Solution', style = 'filled',
                      color = 'lightblue', fillcolor = 'lightblue')
        T.add_node('P', label = 'Pruned', style = 'filled',
                      color = 'red', fillcolor = 'red')
        T.add_node('PC', label = 'Pruned \n Candidate', style = 'filled',
                      color = 'red', fillcolor = 'yellow')
    T.add_edge('C', 'I', style = 'invisible', arrowhead = 'none')
    T.add_edge('I', 'S', style = 'invisible', arrowhead = 'none')
    T.add_edge('S', 'P', style = 'invisible', arrowhead = 'none')
    T.add_edge('P', 'PC', style = 'invisible', arrowhead = 'none')
    T.create_cluster(['C', 'I', 'S', 'P', 'PC'], cluster_attrs)
    # The initial lower bound
    LB = -INFINITY
    # The number of LP's solved, and the number of nodes solved
    node_count = 1
    iter_count = 0
    lp_count = 0
    
    if binary_vars:
        var   = LpVariable.dicts("", VARIABLES, 0, 1)
    else:
        var   = LpVariable.dicts("", VARIABLES)
    
    numCons = len(CONSTRAINTS)
    numVars = len(VARIABLES)
    # List of incumbent solution variable values
    opt = dict([(i, 0) for i in VARIABLES])
    pseudo_u = dict((i, (OBJ[i], 0)) for i in VARIABLES)
    pseudo_d = dict((i, (OBJ[i], 0)) for i in VARIABLES)
    print("===========================================")
    print("Starting Branch and Bound")
    if branch_strategy == MOST_FRACTIONAL:
        print("Most fractional variable")
    elif branch_strategy == FIXED_BRANCHING:
        print("Fixed order")
    elif branch_strategy == PSEUDOCOST_BRANCHING:
        print("Pseudocost brancing")
    else:
        print("Unknown branching strategy %s" %branch_strategy)
    if search_strategy == DEPTH_FIRST:
        print("Depth first search strategy")
    elif search_strategy == BEST_FIRST:
        print("Best first search strategy")
    else:
        print("Unknown search strategy %s" %search_strategy)
    print("===========================================")
    # List of candidate nodes
    Q = PriorityQueue()
    # The current tree depth
    cur_depth = 0
    cur_index = 0
    # Timer
    timer = time.time()
    Q.push(0, -INFINITY, (0, None, None, None, None, None, None))
    # Branch and Bound Loop
    while not Q.isEmpty():
        infeasible = False
        integer_solution = False
        (cur_index, parent, relax, branch_var, branch_var_value, sense,
        rhs) = Q.pop()
        if cur_index is not 0:
            cur_depth = T.get_node_attr(parent, 'level') + 1
        else:
            cur_depth = 0
        print("")
        print("----------------------------------------------------")
        print("")
        if LB > -INFINITY:
            print("Node: %s, Depth: %s, LB: %s" %(cur_index,cur_depth,LB))
        else:
            print("Node: %s, Depth: %s, LB: %s" %(cur_index,cur_depth,"None"))
        if relax is not None and relax <= LB:
            print("Node pruned immediately by bound")
            T.set_node_attr(parent, 'color', 'red')
            continue
        #====================================
        #    LP Relaxation
        #====================================
        # Compute lower bound by LP relaxation
        prob = LpProblem("relax", LpMaximize)
        prob += lpSum([OBJ[i]*var[i] for i in VARIABLES]), "Objective"
        for j in range(numCons):
            prob += (lpSum([MAT[i][j]*var[i] for i in VARIABLES])<=RHS[j],\
                         CONSTRAINTS[j])
        # Fix all prescribed variables
        branch_vars = []
        if cur_index is not 0:
            sys.stdout.write("Branching variables: ")
            branch_vars.append(branch_var)
            if sense == '>=':
                prob += LpConstraint(lpSum(var[branch_var]) >= rhs)
            else:
                prob += LpConstraint(lpSum(var[branch_var]) <= rhs)
            print(branch_var, end=' ')
            pred = parent
            while not str(pred) == '0':
                pred_branch_var = T.get_node_attr(pred, 'branch_var')
                pred_rhs = T.get_node_attr(pred, 'rhs')
                pred_sense = T.get_node_attr(pred, 'sense')
                if pred_sense == '<=':
                    prob += LpConstraint(lpSum(var[pred_branch_var])
                                         <= pred_rhs)
                else:
                    prob += LpConstraint(lpSum(var[pred_branch_var])
                                         >= pred_rhs)
                print(pred_branch_var, end=' ')
                branch_vars.append(pred_branch_var)
                pred = T.get_node_attr(pred, 'parent')
            print()
        # Solve the LP relaxation
        prob.solve()
        lp_count = lp_count +1
        # Check infeasibility
        infeasible = LpStatus[prob.status] == "Infeasible" or \
            LpStatus[prob.status] == "Undefined"
        # Print status
        if infeasible:
            print("LP Solved, status: Infeasible")
        else:
            print("LP Solved, status: %s, obj: %s" %(LpStatus[prob.status],
                                                     value(prob.objective)))
        if(LpStatus[prob.status] == "Optimal"):
            relax = value(prob.objective)
            # Update pseudocost
            if branch_var != None:
                if sense == '<=':
                    pseudo_d[branch_var] = (
                    old_div((pseudo_d[branch_var][0]*pseudo_d[branch_var][1] +
                    old_div((T.get_node_attr(parent, 'obj') - relax),
                    (branch_var_value - rhs))),(pseudo_d[branch_var][1]+1)),
                    pseudo_d[branch_var][1]+1)
                else:
                    pseudo_u[branch_var] = (
                    old_div((pseudo_u[branch_var][0]*pseudo_d[branch_var][1] +
                     old_div((T.get_node_attr(parent, 'obj') - relax),
                     (rhs - branch_var_value))),(pseudo_u[branch_var][1]+1)),
                    pseudo_u[branch_var][1]+1)
            var_values = dict([(i, var[i].varValue) for i in VARIABLES])
            integer_solution = 1
            for i in VARIABLES:
                if (abs(round(var_values[i]) - var_values[i]) > .001):
                    integer_solution = 0
                    break
            # Determine integer_infeasibility_count and
            # Integer_infeasibility_sum for scatterplot and such
            integer_infeasibility_count = 0
            integer_infeasibility_sum = 0.0
            for i in VARIABLES:
                if (var_values[i] not in set([0,1])):
                    integer_infeasibility_count += 1
                    integer_infeasibility_sum += min([var_values[i],
                                                      1.0-var_values[i]])
            if (integer_solution and relax>LB):
                LB = relax
                for i in VARIABLES:
                    # These two have different data structures first one
                    #list, second one dictionary
                    opt[i] = var_values[i]
                print("New best solution found, objective: %s" %relax)
                for i in VARIABLES:
                    if var_values[i] > 0:
                        print("%s = %s" %(i, var_values[i]))
            elif (integer_solution and relax<=LB):
                print("New integer solution found, objective: %s" %relax)
                for i in VARIABLES:
                    if var_values[i] > 0:
                        print("%s = %s" %(i, var_values[i]))
            else:
                print("Fractional solution:")
                for i in VARIABLES:
                    if var_values[i] > 0:
                        print("%s = %s" %(i, var_values[i]))
            #For complete enumeration
            if complete_enumeration:
                relax = LB - 1
        else:
            relax = INFINITY
        if integer_solution:
            print("Integer solution")
            BBstatus = 'S'
            status = 'integer'
            color = 'lightblue'
        elif infeasible:
            print("Infeasible node")
            BBstatus = 'I'
            status = 'infeasible'
            color = 'orange'
        elif not complete_enumeration and relax <= LB:
            print("Node pruned by bound (obj: %s, UB: %s)" %(relax,LB))
            BBstatus = 'P'
            status = 'fathomed'
            color = 'red'
        elif cur_depth >= numVars :
            print("Reached a leaf")
            BBstatus = 'fathomed'
            status = 'L'
        else:
            BBstatus = 'C'
            status = 'candidate'
            color = 'yellow'
        if BBstatus is 'I':
            if T.get_layout() == 'dot2tex':
                label = '\text{I}'
            else:
                label = 'I'
        else:
            label = "%.1f"%relax
        if iter_count == 0:
            if status is not 'candidate':
                integer_infeasibility_count = None
                integer_infeasibility_sum = None
            if status is 'fathomed':
                if T._incumbent_value is None:
                    print('WARNING: Encountered "fathom" line before '+\
                        'first incumbent.')
            T.AddOrUpdateNode(0, None, None, 'candidate', relax,
                             integer_infeasibility_count,
                             integer_infeasibility_sum,
                             label = label,
                             obj = relax, color = color,
                             style = 'filled', fillcolor = color)
            if status is 'integer':
                T._previous_incumbent_value = T._incumbent_value
                T._incumbent_value = relax
                T._incumbent_parent = -1
                T._new_integer_solution = True
#           #Currently broken
#           if ETREE_INSTALLED and T.attr['display'] == 'svg':
#               T.write_as_svg(filename = "node%d" % iter_count,
#                                 nextfile = "node%d" % (iter_count + 1),
#                                 highlight = cur_index)
        else:
            _direction = {'<=':'L', '>=':'R'}
            if status is 'infeasible':
                integer_infeasibility_count = T.get_node_attr(parent,
                                     'integer_infeasibility_count')
                integer_infeasibility_sum = T.get_node_attr(parent,
                                     'integer_infeasibility_sum')
                relax = T.get_node_attr(parent, 'lp_bound')
            elif status is 'fathomed':
                if T._incumbent_value is None:
                    print('WARNING: Encountered "fathom" line before'+\
                        ' first incumbent.')
                    print('  This may indicate an error in the input file.')
            elif status is 'integer':
                integer_infeasibility_count = None
                integer_infeasibility_sum = None
            T.AddOrUpdateNode(cur_index, parent, _direction[sense],
                                 status, relax,
                                 integer_infeasibility_count,
                                 integer_infeasibility_sum,
                                 branch_var = branch_var,
                                 branch_var_value = var_values[branch_var],
                                 sense = sense, rhs = rhs, obj = relax,
                                 color = color, style = 'filled',
                                 label = label, fillcolor = color)
            if status is 'integer':
                T._previous_incumbent_value = T._incumbent_value
                T._incumbent_value = relax
                T._incumbent_parent = parent
                T._new_integer_solution = True
            # Currently Broken
#           if ETREE_INSTALLED and T.attr['display'] == 'svg':
#               T.write_as_svg(filename = "node%d" % iter_count,
#                                 prevfile = "node%d" % (iter_count - 1),
#                                 nextfile = "node%d" % (iter_count + 1),
#                                 highlight = cur_index)
            if T.get_layout() == 'dot2tex':
                _dot2tex_label = {'>=':' \geq ', '<=':' \leq '}
                T.set_edge_attr(parent, cur_index, 'label',
                                   str(branch_var) + _dot2tex_label[sense] +
                                   str(rhs))
            else:
                T.set_edge_attr(parent, cur_index, 'label',
                                   str(branch_var) + sense + str(rhs))
        iter_count += 1
        if BBstatus == 'C':
            # Branching:
            # Choose a variable for branching
            branching_var = None
            if branch_strategy == FIXED_BRANCHING:
                #fixed order
                for i in VARIABLES:
                    frac = min(var[i].varValue-math.floor(var[i].varValue),
                               math.ceil(var[i].varValue) - var[i].varValue)
                    if (frac > 0):
                        min_frac = frac
                        branching_var = i
                        # TODO(aykut): understand this break
                        break
            elif branch_strategy == MOST_FRACTIONAL:
                #most fractional variable
                min_frac = -1
                for i in VARIABLES:
                    frac = min(var[i].varValue-math.floor(var[i].varValue),
                               math.ceil(var[i].varValue)- var[i].varValue)
                    if (frac> min_frac):
                        min_frac = frac
                        branching_var = i
            elif branch_strategy == PSEUDOCOST_BRANCHING:
                scores = {}
                for i in VARIABLES:
                    # find the fractional solutions
                    if (var[i].varValue - math.floor(var[i].varValue)) != 0:
                        scores[i] = min(pseudo_u[i][0]*(1-var[i].varValue),
                                        pseudo_d[i][0]*var[i].varValue)
                    # sort the dictionary by value
                branching_var = sorted(list(scores.items()),
                                       key=lambda x : x[1])[-1][0]
            else:
                print("Unknown branching strategy %s" %branch_strategy)
                exit()
            if branching_var is not None:
                print("Branching on variable %s" %branching_var)
            #Create new nodes
            if search_strategy == DEPTH_FIRST:
                priority = (-cur_depth - 1, -cur_depth - 1)
            elif search_strategy == BEST_FIRST:
                priority = (-relax, -relax)
            elif search_strategy == BEST_ESTIMATE:
                priority = (-relax - pseudo_d[branching_var][0]*\
                                 (math.floor(var[branching_var].varValue) -\
                                      var[branching_var].varValue),
                            -relax + pseudo_u[branching_var][0]*\
                                 (math.ceil(var[branching_var].varValue) -\
                                      var[branching_var].varValue))
            node_count += 1
            Q.push(node_count, priority[0], (node_count, cur_index, relax, branching_var,
                    var_values[branching_var],
                    '<=', math.floor(var[branching_var].varValue)))
            node_count += 1
            Q.push(node_count, priority[1], (node_count, cur_index, relax, branching_var,
                    var_values[branching_var],
                    '>=', math.ceil(var[branching_var].varValue)))
            T.set_node_attr(cur_index, color, 'green')
        if T.root is not None and display_interval is not None and\
                iter_count%display_interval == 0:
            T.display(count=iter_count)

    timer = int(math.ceil((time.time()-timer)*1000))
    print("")
    print("===========================================")
    print("Branch and bound completed in %sms" %timer)
    print("Strategy: %s" %branch_strategy)
    if complete_enumeration:
        print("Complete enumeration")
    print("%s nodes visited " %node_count)
    print("%s LP's solved" %lp_count)
    print("===========================================")
    print("Optimal solution")
    #print optimal solution
    for i in sorted(VARIABLES):
        if opt[i] > 0:
            print("%s = %s" %(i, opt[i]))
    print("Objective function value")
    print(LB)
    print("===========================================")
    if T.attr['display'] is not 'off':
        T.display(count=iter_count)
    T._lp_count = lp_count
    return opt, LB
Exemplo n.º 45
0
    numVars = 40
    numCons = 20
    density = 0.2
    maxObjCoeff = 10
    maxConsCoeff = 10
    CONSTRAINTS = ["C"+str(i) for i in range(numCons)]
    if layout == 'ladot':
        VARIABLES = ["x_{"+str(i)+"}" for i in range(numVars)]
    else:
        VARIABLES = ["x"+str(i) for i in range(numVars)]
    OBJ = {i : randint(1, maxObjCoeff) for i in VARIABLES}
    MAT = {i : [randint(1, maxConsCoeff) if random() <= density else 0
                for j in CONSTRAINTS] for i in VARIABLES}
    RHS = [randint(int(numVars*density*maxConsCoeff/2), int(numVars*density*maxConsCoeff/1.5)) for i in CONSTRAINTS]

var   = LpVariable.dicts("", VARIABLES, 0, 1)

################################################################

#Branching strategies
MOST_FRAC = "MOST FRACTIONAL"
FIXED = "FIXED"

#search strategies
DEPTH_FIRST = "Depth First"
BEST_FIRST = "Best First"

#Selected branching strategy
branch_strategy = FIXED
search_strategy = BEST_FIRST
Exemplo n.º 46
0
def schedule(Jobs, Agents, D, C, R, B, P, M):
    """
    Finds the optimal scheduling of Jobs to Agents (workers) given
    Jobs - a set of Jobs (an iterable of hashable objects)
    Agents - a set of Agents/workers (an iterable of hashable objects)
    D - Dictionary detailing execution cost of running jobs on agents :
        D[job, agent] = time to run job on agent
    C - Dictionary detailing Communication cost sending results  of jobs
        between  agents :
        C[job, a1, a2] = time to comm results of job on from a1 to a2
    R - Additional constraint on start time of jobs, usually defaultdict(0)
    B - Dict saying which jobs can run on which agents:
        B[job, agent] == 1 if job can run on agent
    P - Dictionary containing precedence constraints - specifies DAG:
        P[job1, job2] == 1 if job1 immediately precedes job2
    M - Upper bound on makespan

    Returns
    prob - the pulp problem instance
    X - Dictionary detailing which jobs were run on which agents:
        X[job][agent] == 1 iff job was run on agent
    S - Starting time of each job
    Cmax - Optimal makespan

    """

    # Set up global precedence matrix
    Q = PtoQ(P)


    # PULP SETUP
    # The prob variable is created to contain the problem data
    prob = LpProblem("Scheduling Problem - Tompkins Formulation", LpMinimize)

    # The problem variables are created
    # X - 1 if job is scheduled to be completed by agent
    X = LpVariable.dicts("X", (Jobs, Agents), 0, 1, LpInteger)
    # S - Scheduled start time of job
    S = LpVariable.dicts("S", Jobs, 0, M, LpContinuous)

    # Theta - Whether two jobs overlap
    Theta = LpVariable.dicts("Theta", (Jobs, Jobs), 0, 1, LpInteger)
    # Makespan
    Cmax = LpVariable("C_max", 0, M, LpContinuous)

    #####################
    # 4.2.2 CONSTRAINTS #
    #####################

    # Objective function
    prob += Cmax

    # Subject to:

    # 4-1 Cmax is greater than the ending schedule time of all jobs
    for job in Jobs:
        prob += Cmax >= S[job] + lpSum([D[job, agent] * X[job][agent]
            for agent in Agents if B[job, agent]>0])

    # 4-2 an agent cannot be assigned a job unless it provides the services
    # necessary to complete that job
    for job in Jobs:
        for agent in Agents:
            if B[job, agent] == 0:
                prob += X[job][agent] == 0

    # 4-3 specifies that each job must be assigned once to exactly one agent
    for job in Jobs:
        prob += lpSum([X[job][agent] for agent in Agents]) == 1

    # 4-4 a job cannot start until its predecessors are completed and data has
    # been communicated to it if the preceding jobs were executed on a
    # different agent
    for (j,k), prec in P.items():
        if prec>0: # if j precedes k in the DAG
            prob += S[k]>=S[j]
            for a in Agents:
                for b in Agents:
                    if B[j,a] and B[k,b]: # a is capable of j and b capable of k
                        prob += S[k] >= (S[j] +
                                (D[j,a] + C[j,a,b]) * (X[j][a] + X[k][b] -1))

    # 4-5 a job cannot start until after its release time
    for job in Jobs:
        if R[job]>0:
            prob += S[job] >= R[job]

    # Collectively, (4-6) and (4-7) specify that an agent may process at most
    # one job at a time

    # 4-6
    for j in Jobs:
        for k in Jobs:
            if j==k or Q[j,k]!=0:
                continue
            prob += S[k] - lpSum([D[j,a]*X[j][a] for a in Agents]) - S[j] >= (
                    -M*Theta[j][k])
            # The following line had a < in the paper. We've switched to <=
            # Uncertain if this is a good idea
            prob += S[k] - lpSum([D[j,a]*X[j][a] for a in Agents]) - S[j] <= (
                    M*(1-Theta[j][k]))
    # 4-7 if two jobs j and k are assigned to the same agent, their execution
    # times may not overlap
    for j in Jobs:
        for k in Jobs:
            for a in Agents:
                prob += X[j][a] + X[k][a] + Theta[j][k] + Theta[k][j] <= 3

    return prob, X, S, Cmax
Exemplo n.º 47
0
Arquivo: milp.py Projeto: coin-or/Dip
numBlockVars = [10]
numBlockCons = [5]
numLinkingCons = 10
numVars = sum(numBlockVars)
numCons = sum(numBlockCons) + numLinkingCons

VARIABLES = dict(((i, j), 0) for i in range(numBlocks) 
                 for j in range(numBlockVars[i]))  

CONSTRAINTS = []
for k in range(numBlocks):
    CONSTRAINTS.append(["C"+str(k)+"_"+str(j) for j in range(numCons)])
CONSTRAINTS.append(["C"+str(numBlocks)+"_"+str(j) for j in range(numCons)])

#Generate random MILP
var = LpVariable.dicts("x", VARIABLES, 0, 1, LpBinary)
numCons = len(CONSTRAINTS)
numVars = len(VARIABLES)

OBJ, MAT, RHS = GenerateRandomBlock(VARIABLES, CONSTRAINTS[numBlocks])

prob += -lpSum([OBJ[i]*var[i] for i in var]), "Objective"

#Linking constraints
for j in CONSTRAINTS[numBlocks]:
    prob += lpSum([MAT[i, j]*var[i] for i in var]) <= RHS[j], j

#Blocks    
for k in range(numBlocks):
    OBJ, MAT, RHS = GenerateRandomBlock([(k, i) for i in range(numBlockVars[k])], 
                                        CONSTRAINTS[k])
Exemplo n.º 48
0
ARC_COSTS.update(CUST_TRANS)
ARCS = ARC_COSTS.keys()

def cross(i1, i2):
    r = []
    for a in i1:
        for b in i2:
            r.append((a, b))
    return r

LOC_SIZES = cross(LOCATIONS, SIZES)

prob = dippy.DipProblem("Coke", LpMinimize)

# create variables
buildVars = LpVariable.dicts("Build", LOC_SIZES, None, \
                             None, LpBinary)
prob.buildVars = buildVars

# create arcs
flowVars = LpVariable.dicts("Arcs", ARCS)
for a in ARCS:
    flowVars[a].bounds(0, BIG_M)

prob.SIZES = SIZES

# objective
prob += 1e6 * lpSum(buildVars[(l, s)] * SIZE_COSTS[s] \
                    for (l, s) in LOC_SIZES) + \
              lpSum(flowVars[(s, d)] * ARC_COSTS[(s, d)] \
                    for (s, d) in ARCS), "min"
Exemplo n.º 49
0
    x -= (x >> 1) & 0x5555555555555555
    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)
    x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f
    return ((x * 0x0101010101010101) & 0xffffffffffffffff ) >> 56

labels = range(2**nmice)
# Only use labels with a Hamming weight <= 3
nonzeros = [i for i in labels if popcount(i) in [0,1,2,3]]

# Initialize problem
prob = LpProblem("drunk_mice", LpMinimize)

# This is the answer, the allocation of bottles to each label:
allocs = LpVariable.dicts(
    "alloc",
    nonzeros,
    0, nbottles,
    LpInteger,
)

# They must sum to nbottles:
prob += lpSum(allocs) == nbottles

# This is the number we are minimizing
worst_loss = LpVariable(
    "worst_loss",
    npoisoned,
    nbottles,
)

prob += worst_loss, "obj"
Exemplo n.º 50
0
from math import floor, ceil

tol = pow(pow(2, -24), 2.0 / 3.0)
debug_print = False

REQUIREMENT = data.REQUIREMENT
PRODUCTS = data.PRODUCTS
LOCATIONS = data.LOCATIONS
CAPACITY = data.CAPACITY

print REQUIREMENT

prob = dippy.DipProblem("Bin Packing")

assign_vars = LpVariable.dicts("AtLocation",
              [(i, j) for i in data.LOCATIONS
                      for j in data.PRODUCTS],
              0, 1, LpBinary)
use_vars    = LpVariable.dicts("UseLocation",
              data.LOCATIONS, 0, 1, LpBinary)
waste_vars  = LpVariable.dicts("Waste",
              data.LOCATIONS, 0, data.CAPACITY)

# objective: minimise waste
prob += lpSum(waste_vars[i] for i in LOCATIONS), "min"

# assignment constraints
for j in PRODUCTS:
    prob += lpSum(assign_vars[(i, j)] for i in LOCATIONS) == 1

# Aggregate capacity constraints
for i in LOCATIONS:
Exemplo n.º 51
0
try:
    from facility_ex2 import ASSIGNMENTS
except ImportError:
    ASSIGNMENTS = [(i, j) for i in LOCATIONS for j in PRODUCTS]

try:
    from facility_ex2 import ASSIGNMENT_COSTS
except ImportError:
    ASSIGNMENT_COSTS = dict((i, 0) for i in ASSIGNMENTS)

display_mode = 'xdot'

prob = dippy.DipProblem("Facility Location", display_mode = display_mode,
                        layout = 'dot', display_interval = 0)

assign_vars = LpVariable.dicts("x", ASSIGNMENTS, 0, 1, LpBinary)
use_vars    = LpVariable.dicts("y", LOCATIONS, 0, 1, LpBinary)

debug_print = False

debug_print_lp = False

prob += (lpSum(use_vars[i] * FIXED_COST[i] for i in LOCATIONS) +
         lpSum(assign_vars[j] * ASSIGNMENT_COSTS[j] for j in ASSIGNMENTS), 
         "min")

# assignment constraints
for j in PRODUCTS:
    prob += lpSum(assign_vars[(i, j)] for i in LOCATIONS) == 1

# Aggregate capacity constraints
Exemplo n.º 52
0
	def learn_two_cat2(self, performance_table):
		"""This version of learnTwoCat checks whether or not an alternative is to be kept
		in the learning process. This method is also faster than the previous version
		""" 
		
		if len(self.categories) != 2:
			raise SemanticError, "The learnTwoCat() method requires exactly two categories."

		prob = LpProblem("twoCat2", LpMaximize)
		
		alts = filter(lambda a: a.__class__.__name__ != "LimitProfile", performance_table.alts)
		crits = self.crits

		alts_name = [alt.name for alt in alts]
		crits_name = [crit.name for crit in crits]

		self.categories.sort(key=lambda c: c.rank)

		alts1 = [alt for alt in alts if alt.category == self.categories[0]]
		alts2 = [alt for alt in alts if alt.category == self.categories[1]]

		#small float number
		epsilon = 0.0001

		#variables (v: variable, d: dict of variables)
		v_lambda = LpVariable("lambda", lowBound=0.5, upBound=1)
		d_gamma = LpVariable.dicts("gamma", alts_name, cat=LpBinary)
		d_p = LpVariable.dicts("p", crits_name, lowBound=0, upBound=1)
		d_gb = LpVariable.dicts("gb", crits_name, lowBound=0, upBound=1)
		d_delta = LpVariable.dicts("delta", \
			[alt.name + crit.name for alt in alts for crit in crits]\
			, cat=LpBinary)
		d_c = LpVariable.dicts("c", \
			[alt.name + crit.name for alt in alts for crit in crits]\
			, lowBound=0, upBound=1)

		#maximize
		prob += sum(d_gamma[alt.name] for alt in alts)

		#constraints
		for alt in alts2:
			prob += sum(d_c[alt.name + crit.name] for crit in crits) + epsilon <= v_lambda + 2 * (1 - d_gamma[alt.name])
		for alt in alts1:
			prob += sum(d_c[alt.name + crit.name] for crit in crits) >= v_lambda - 2 * (1 - d_gamma[alt.name])
			
		for alt in alts:
			for crit in crits:
				prob += d_c[alt.name + crit.name] <= d_p[crit.name]
				prob += d_c[alt.name + crit.name] <= d_delta[alt.name + crit.name]
				prob += d_c[alt.name + crit.name] >= d_delta[alt.name + crit.name] + d_p[crit.name] - 1
				prob += d_delta[alt.name + crit.name] >= performance_table[alt][crit] - d_gb[crit.name] + epsilon
				prob += d_delta[alt.name + crit.name] <= performance_table[alt][crit] - d_gb[crit.name] + 1
				
		prob += sum(d_p[crit.name] for crit in crits)  == 1

		#solver
		GLPK().solve(prob)

		#update parameters
		self.cutting_threshold = v_lambda.value()

		for crit in crits:
			crit.weight = d_p[crit.name].value()

		for crit in crits:
			self.lp_performance_table[self.limit_profiles[0]][crit] = d_gb[crit.name].value()
		
		self.ignoredAlternatives = []
		for alt in alts:
			if d_gamma[alt.name].value() == 0:
				self.ignoredAlternatives.append(alt)
Exemplo n.º 53
0
	def learn(self, performance_table):
		"""Learn parameters"""

		prob = LpProblem("Learn", LpMaximize)

		alts = filter(lambda a: a.__class__.__name__ != "LimitProfile", performance_table.alts)
		crits = self.crits

		alts_name = [alt.name for alt in alts]
		crits_name = [crit.name for crit in crits]
		
		categories = self.categories
		
		categories.sort(key=lambda c: c.rank, reverse=True)	
		
		categoriesUp = list(categories)
		firstCat = categoriesUp.pop(0)
		
		categoriesDown = list(categories)
		lastCat = categoriesDown.pop()
		
		categories0 = list(categories)
		categories0.insert(0, Category(rank = (categories[0].rank + 1), name = "fake")) #add a fake category on the first position
				
		alternativesByCat = {}
		for cat in categories:
			alternativesByCat[cat] = [alt for alt in alts if alt.category == cat]
			
		#small float number
		epsilon = 0.000001

		#variables (v: variable, d: dict of variables)
		v_lambda = LpVariable("lambda", lowBound=0.5, upBound=1)
		v_alpha = LpVariable("alpha", lowBound=0)
		d_x = LpVariable.dicts("x", alts_name, lowBound=0)
		d_y = LpVariable.dicts("y", alts_name, lowBound=0)
		d_p = LpVariable.dicts("p", crits_name, lowBound=0, upBound=1)
		d_gb = LpVariable.dicts("gb", \
								[crit.name + cat.name for crit in crits for cat in categories0], \
								lowBound=0, \
								upBound=1)
		d_deltaInf = LpVariable.dicts("deltaInf", \
									  [alt.name + crit.name for alt in alts for crit in crits], \
									  cat=LpBinary)
		d_deltaSup = LpVariable.dicts("deltaSup", \
									  [alt.name + crit.name for alt in alts for crit in crits], \
									  cat=LpBinary)
		d_cInf = LpVariable.dicts("cInf", \
								  [alt.name + crit.name for alt in alts for crit in crits], \
								  lowBound=0, upBound=1)
		d_cSup = LpVariable.dicts("cSup", \
								  [alt.name + crit.name for alt in alts for crit in crits], \
								  lowBound=0, upBound=1)

		#maximize
		prob += v_alpha

		#constraints
		for crit in crits:
			prob += d_gb[crit.name + "fake"] == 0
			prob += d_gb[crit.name + lastCat.name] == 1
		

		for cat in categoriesDown:
			for alt in alternativesByCat[cat]:
				prob += sum(d_cSup[alt.name + crit.name] for crit in crits) + d_x[alt.name] == v_lambda
		for cat in categoriesUp:
			for alt in alternativesByCat[cat]:
				prob += sum(d_cInf[alt.name + crit.name] for crit in crits) == v_lambda + d_y[alt.name]
				
		for alt in alts:
			prob += v_alpha <= d_x[alt.name]
			prob += v_alpha <= d_y[alt.name]
			prob += d_x[alt.name] >= epsilon
			
			for crit in crits:
				prob += d_cInf[alt.name + crit.name] <= d_p[crit.name]
				prob += d_cSup[alt.name + crit.name] <= d_p[crit.name]
				prob += d_cInf[alt.name + crit.name] <= d_deltaInf[alt.name + crit.name]
				prob += d_cSup[alt.name + crit.name] <= d_deltaSup[alt.name + crit.name]
				prob += d_cInf[alt.name + crit.name] >= d_deltaInf[alt.name + crit.name] + d_p[crit.name] - 1
				prob += d_cSup[alt.name + crit.name] >= d_deltaSup[alt.name + crit.name] + d_p[crit.name] - 1
				
		prev_cat_name = "fake"
		for cat in categories:
			for alt in alternativesByCat[cat]:
				for crit in crits:
					prob += d_deltaInf[alt.name + crit.name] >= performance_table[alt][crit] - d_gb[crit.name + prev_cat_name] + epsilon
					prob += d_deltaSup[alt.name + crit.name] >= performance_table[alt][crit] - d_gb[crit.name + cat.name] + epsilon
					prob += d_deltaInf[alt.name + crit.name] <= performance_table[alt][crit] - d_gb[crit.name + prev_cat_name] + 1
					prob += d_deltaSup[alt.name + crit.name] <= performance_table[alt][crit] - d_gb[crit.name + cat.name] + 1
			prev_cat_name = cat.name

		prev_cat_name = firstCat.name
		for cat in categoriesUp:
			for crit in crits:
				prob += d_gb[crit.name + cat.name] >= d_gb[crit.name + prev_cat_name]
			prev_cat_name = cat.name
			
		prob += sum(d_p[crit.name] for crit in crits) == 1
		
		print prob
		
		#solver
		GLPK().solve(prob)

		#prob.writeLP("SpamClassification.lp")
		#status = prob.solve()


		#update parameters
		self.cutting_threshold = v_lambda.value()

		for crit in crits:
			crit.weight = d_p[crit.name].value()
			
		for cat in categoriesDown:
			for crit in crits:
				performance_table[cat.lp_sup][crit] = d_gb[crit.name + cat.name].value()
Exemplo n.º 54
0
	def learn2(self, performance_table):
		"""This version of learn checks whether or not an alternative is to be kept
		in the learning process. This method is also faster than the previous version
		""" 

		prob = LpProblem("Learn", LpMaximize)

		alts = filter(lambda a: a.__class__.__name__ != "LimitProfile", performance_table.alts)
		crits = self.crits

		alts_name = [alt.name for alt in alts]
		crits_name = [crit.name for crit in crits]
		
		categories = self.categories
		
		categories.sort(key=lambda c: c.rank, reverse=True)	
		
		categoriesUp = list(categories)
		firstCat = categoriesUp.pop(0)
		
		categoriesDown = list(categories)
		lastCat = categoriesDown.pop()
		
		categories0 = list(categories)
		categories0.insert(0, Category(rank = (categories[0].rank + 1), name = "fake")) #add a fake category on the first position
				
		alternativesByCat = {}
		for cat in categories:
			alternativesByCat[cat] = [alt for alt in alts if alt.category == cat]
			
		#small float number
		epsilon = 0.001

		#variables (v: variable, d: dict of variables)
		v_lambda = LpVariable("lambda", lowBound=0.5, upBound=1)
		d_gamma = LpVariable.dicts("gamma", alts_name, cat=LpBinary)
		d_p = LpVariable.dicts("p", crits_name, lowBound=0, upBound=1)
		d_gb = LpVariable.dicts("gb", \
								[crit.name + cat.name for crit in crits for cat in categories0], \
								lowBound=0, \
								upBound=1)
		d_deltaInf = LpVariable.dicts("deltaInf", \
									  [alt.name + crit.name for alt in alts for crit in crits], \
									  cat=LpBinary)
		d_deltaSup = LpVariable.dicts("deltaSup", \
									  [alt.name + crit.name for alt in alts for crit in crits], \
									  cat=LpBinary)
		d_cInf = LpVariable.dicts("cInf", \
								  [alt.name + crit.name for alt in alts for crit in crits], \
								  lowBound=0, upBound=1)
		d_cSup = LpVariable.dicts("cSup", \
								  [alt.name + crit.name for alt in alts for crit in crits], \
								  lowBound=0, upBound=1)

		#maximize
		prob += sum(d_gamma[alt.name] for alt in alts)

		#constraints		
		for crit in crits:
			prob += d_gb[crit.name + "fake"] == 0
			prob += d_gb[crit.name + lastCat.name] == 1
					
		for cat in categoriesDown:
			for alt in alternativesByCat[cat]:
				tmp =  alt.name + crit.name #fixed a weird bug with pulp
				prob += sum(d_cSup[tmp] for crit in crits) + epsilon <= v_lambda + 2 * (1 - d_gamma[alt.name])
		for cat in categoriesUp:
			for alt in alternativesByCat[cat]:
				tmp =  alt.name + crit.name #fixed a weird bug with pulp
				prob += sum(d_cInf[tmp] for crit in crits) >= v_lambda - 2 * (1 - d_gamma[alt.name])					

		for alt in alts:	   
			for crit in crits:
				prob += d_cInf[alt.name + crit.name] <= d_p[crit.name]
				prob += d_cSup[alt.name + crit.name] <= d_p[crit.name]
				prob += d_cInf[alt.name + crit.name] <= d_deltaInf[alt.name + crit.name]
				prob += d_cSup[alt.name + crit.name] <= d_deltaSup[alt.name + crit.name]
				prob += d_cInf[alt.name + crit.name] >= d_deltaInf[alt.name + crit.name] + d_p[crit.name] - 1
				prob += d_cSup[alt.name + crit.name] >= d_deltaSup[alt.name + crit.name] + d_p[crit.name] - 1
				
		prev_cat_name = "fake"
		for cat in categories:
			for alt in alternativesByCat[cat]:
				for crit in crits:
					prob += d_deltaInf[alt.name + crit.name] >= performance_table[alt][crit] - d_gb[crit.name + prev_cat_name] + epsilon
					prob += d_deltaSup[alt.name + crit.name] >= performance_table[alt][crit] - d_gb[crit.name + cat.name] + epsilon
					prob += d_deltaInf[alt.name + crit.name] <= performance_table[alt][crit] - d_gb[crit.name + prev_cat_name] + 1
					prob += d_deltaSup[alt.name + crit.name] <= performance_table[alt][crit] - d_gb[crit.name + cat.name] + 1
			prev_cat_name = cat.name

		prev_cat_name = firstCat.name
		for cat in categoriesUp:
			for crit in crits:
				prob += d_gb[crit.name + cat.name] >= d_gb[crit.name + prev_cat_name]
			prev_cat_name = cat.name
			
		prob += sum(d_p[crit.name] for crit in crits) == 1
		
		print prob
		
		#solver
		GLPK().solve(prob)
		
		#update parameters
		self.cutting_threshold = v_lambda.value()

		for crit in crits:
			crit.weight = d_p[crit.name].value()
			
		for cat in categoriesDown:
			for crit in crits:
				performance_table[cat.lp_sup][crit] = d_gb[crit.name + cat.name].value()		
				
		self.ignoredAlternatives = []
		for alt in alts:
			if d_gamma[alt.name].value() == 0:
				self.ignoredAlternatives.append(alt)
def weak_rev_lin_con(crn, eps, ubound):
    
    m = crn.n_complexes
    n = crn.n_species
    
    # Y is n by m
    Y = np.array(crn.complex_matrix).astype(np.float64)
    
    # Ak is m by m
    Ak = np.array(crn.kinetic_matrix).astype(np.float64)
    
    # M is n by m
    M = Y.dot(Ak)

    print("Input CRN defined by\nY =\n", Y)
    print("\nM =\n", M)    
    print("\nAk =\n", Ak)
    print("\nComputing linearly conjugate network with min deficiency ... START\n")

    # Ranges for iteration
    col_range = range(1, m+1)
    row_range = range(1, n+1)

    # Set up problem model object
    prob = LpProblem("Weakly Reversible Linearly Conjugate Network", LpMaximize)
    
    # Get a list of all off-diagonal entries to use later to greatly
    # simplify loops
    off_diag = [(i, j) for i,j in product(col_range, repeat=2) if i != j]
    
    # Decision variables for matrix A, only need off-diagonal since A
    # has zero-sum columns
    A = LpVariable.dicts("A", [(i, j) for i in col_range for j in col_range])
    Ah = LpVariable.dicts("Ah", [(i, j) for i in col_range for j in col_range])
     
    # Decision variables for the diagonal of T
    T = LpVariable.dicts("T", row_range, eps, ubound)
    
    # Binary variables for counting partitions used and assigning complexes to linkage classes
    delta = LpVariable.dicts("delta", off_diag, 0, 1, "Integer")
    
    # Objective
    prob += -lpSum(delta[i, j] for (i,j) in off_diag)
    
    # Y*A = T*M
    for i in row_range:
        for j in col_range:
            prob += lpSum( Y[i-1, k-1]*A[k, j] for k in col_range ) == M[i-1, j-1]*T[i]
            
    # A and Ah have zero-sum columns
    for j in col_range:
        prob += lpSum( A[i,j] for i in col_range ) == 0    
        prob += lpSum( Ah[i,j] for i in col_range ) == 0
        prob += lpSum( Ah[j,i] for i in col_range ) == 0
    
    # Off-diagonal entries are nonnegative and are switch on/off by delta[i,j]
    for (i,j) in off_diag:
        # A constraints
        prob += A[i, j] >= 0
        prob += A[i, j] - eps*delta[i, j] >= 0
        prob += A[i, j] - ubound*delta[i, j] <= 0
        
        # Ah constraints
        prob += Ah[i, j] >= 0
        prob += Ah[i, j] - eps*delta[i, j] >= 0
        prob += Ah[i, j] - ubound*delta[i, j] <= 0
        
    # Diagonal entries of A, Ah are non-positive
    for j in col_range:
        prob += A[j, j] <= 0
        prob += Ah[j, j] <= 0
        
    status = prob.solve(solver=CPLEX()) 
    #print(prob)
    
    # Problem successfully solved, report results
    if status == 1:
        
        # Get solutions to problem
        Tsol = np.zeros((n, n))
        Asol = np.zeros((m,m))
        
        for i in col_range:
            for j in col_range:
                Asol[i-1, j-1] = value(A[i, j])
        
        for i in row_range:
            Tsol[i-1, i-1] = value(T[i])
        
        print("\nA =\n", Asol)
        print("\nT =\n", Tsol)

    else:
        print("No solution found")
Exemplo n.º 56
0
def opAss_LP(machineList, PBlist, PBskills, previousAssignment={}, weightFactors = [2, 1, 0, 2, 1, 1], Tool={}):
    
    from pulp import LpProblem, LpMaximize, LpVariable, LpBinary, lpSum, LpStatus
    import pulp
    import copy
    import glob
    import os 
    import time
    from Globals import G

    startPulp=time.time()
    machines = machineList.keys()
    sumWIP = float(sum([machineList[mach]['WIP'] for mach in machines ]))
        
    # define LP problem    
    prob = LpProblem("PBassignment", LpMaximize)
    obj = []
        
    # declare variables...binary assignment variables (operator i to machine j)
    PB_ass = LpVariable.dicts('PB', [(oper,mach) for oper in PBlist for mach in machines if machineList[mach]['stationID'] in PBskills[oper]] , 0, 1, cat=pulp.LpBinary)
    
    # objective...assignment of PBs to stations with higher WIP...sum of WIP associated with stations where PB is assigned
    if weightFactors[0]>0 and sumWIP>0:
        obj.append([machineList[mach]['WIP']*PB_ass[(oper,mach)]*weightFactors[0]/float(sumWIP) for oper in PBlist for mach in machines if machineList[mach]['stationID'] in PBskills[oper]])
    
    
    # second set of variables (delta assignment between stations) to facilitate the distribution of PBs across different stations
    if weightFactors[1]>0:
        stationGroup = {}
        for mach in machines:
            if machineList[mach]['stationID'] not in stationGroup:
                stationGroup[machineList[mach]['stationID']] = []
            stationGroup[machineList[mach]['stationID']].append(mach)
        Delta_Station = LpVariable.dicts("D_station", [(st1, st2) for i1, st1 in enumerate(stationGroup.keys()) for st2 in stationGroup.keys()[i1 + 1:]])
    
        # calculate global max number of machines within a station that will be used as dividers for Delta_Station  
        maxNoMachines = 0
        for st in stationGroup:
            if len(stationGroup[st]) > maxNoMachines:
                maxNoMachines = len(stationGroup[st])
    
        # calculation of DeltaStation values 
        for i, st1 in enumerate(stationGroup.keys()):
            tempList = []
            for mach1 in stationGroup[st1]:
                for oper1 in PBlist:
                    if st1 in PBskills[oper1]:
                        tempList.append(PB_ass[(oper1,mach1)]/float(maxNoMachines))
        
            for st2 in stationGroup.keys()[i+1:]:
            
                finalList = copy.copy(tempList)
                for mach2 in stationGroup[st2]:                
                    for oper2 in PBlist:
                        if st2 in PBskills[oper2]:
                            finalList.append(PB_ass[(oper2,mach2)]*-1/float(maxNoMachines))  
                
                prob += lpSum(finalList)>= Delta_Station[(st1,st2)]
                prob += lpSum([i*-1 for i in finalList])>= Delta_Station[(st1,st2)]
            
        # integration of second obj
        normalisingFactorDeltaStation = 0
        for i in range(len(stationGroup)):
            normalisingFactorDeltaStation += i
        for i1, st1 in enumerate(stationGroup.keys()):
            for st2 in stationGroup.keys()[i1+1:]:
                obj.append(Delta_Station[(st1,st2)]*weightFactors[1]/float(normalisingFactorDeltaStation) )
        
    # min variation in PB assignment
    if weightFactors[2]>0:
        Delta_Assignment = []
        OldAss = {}
        for pb in previousAssignment:
            if pb in PBlist:
                for station in PBskills[pb]:
                    for mach in machineList:
                        if machineList[mach]['stationID'] == station:
                            Delta_Assignment.append([pb, mach])
                            if previousAssignment[pb] == mach:
                                OldAss[(pb,mach)] = 1
                            else:
                                OldAss[(pb,mach)] = 0
                
    
        # create delta assignment variables
        Delta_Ass = LpVariable.dicts("D_Ass",[(d[0],d[1]) for d in Delta_Assignment])
    
        # integration of third objective
        for d in Delta_Assignment:
            obj.append(Delta_Ass[(d[0], d[1])]*(-1.0*weightFactors[2]/(2*len(previousAssignment))) )

        # calculation of Delta_Ass
        for d in Delta_Assignment:
            if OldAss[(d[0],d[1])] == 1:
                prob += lpSum(OldAss[(d[0],d[1])] - PB_ass[(d[0],d[1])]) <= Delta_Ass[(d[0],d[1])]
            else:
                prob += lpSum(PB_ass[(d[0],d[1])] - OldAss[(d[0],d[1])]) <= Delta_Ass[(d[0],d[1])]  
            
            
    # 4th obj = fill a subline
    if weightFactors[3]>0:
        # verify whether there are machines active in the sublines
        subline={0:{'noMach':0, 'WIP':0}, 1:{'noMach':0, 'WIP':0}}
        for mach in machineList:
            if machineList[mach]['stationID'] in [0,1,2]:
                subline[machineList[mach]['machineID']]['noMach'] += 1
                subline[machineList[mach]['machineID']]['WIP'] += machineList[mach]['WIP']
    
        chosenSubLine = False      
    
        # choose subline to be filled first
        if subline[0]['noMach'] == 3:        
            # case when both sublines are fully active
            if subline[1]['noMach'] == 3:
                if subline[0]['WIP'] >= subline [1]['WIP']:
                    chosenSubLine = 1
                else:
                    chosenSubLine = 2        
            else:
                chosenSubLine = 1
    
        elif subline[1]['noMach'] == 3:
            chosenSubLine = 2
    
        #create variable for the chosen subline
        if chosenSubLine:
            chosenSubLine -= 1
            subLine = LpVariable('SubL', lowBound=0)
            sub = []
            for station in range(3):
                mach = Tool[station][chosenSubLine].name        #'St'+str(station)+'_M'+str(chosenSubLine)
                for oper in PBlist:
                    if station in PBskills[oper]:
                        sub.append(PB_ass[(oper,mach)])
            
            
            prob += lpSum(sub) >= subLine
            chosenSubLine+=1
            obj.append(subLine*weightFactors[3]/3.0)  
            
            
    # 5th objective: prioritise machines with furthest in time last assignment 
    LastAssignmentSum = float(sum([machineList[mach]['lastAssignment'] for mach in machines ]))
    if LastAssignmentSum > 0 and weightFactors[4]>0:
        obj += [machineList[mach]['lastAssignment']*PB_ass[(oper,mach)]*weightFactors[4]/float(LastAssignmentSum) for oper in PBlist for mach in machines if machineList[mach]['stationID'] in PBskills[oper]]
       
    # 6th objective: max the number of pb assigned
    if weightFactors[5]>0:
        obj += [PB_ass[(oper,mach)]*weightFactors[5]/float(len(PBlist)) for oper in PBlist for mach in machines if machineList[mach]['stationID'] in PBskills[oper]]
       
    prob += lpSum(obj)
        
    # constraint 1: # operators assigned to a station <= 1
    for machine in machines:
        prob += lpSum([PB_ass[(oper,machine)] for oper in PBlist if machineList[machine]['stationID'] in PBskills[oper]]) <= 1
        
    # constraint 2: # machines assigned to an operator <= 1
    for operator in PBlist:
        prob += lpSum([PB_ass[(operator,machine)] for machine in machines if machineList[machine]['stationID'] in PBskills[operator]]) <= 1
            
            
    # write the problem data to an .lp file.
    prob.writeLP("PBassignment.lp") 
    
    prob.solve()
    
    if LpStatus[prob.status] != 'Optimal':
        print 'WARNING: LP solution ', LpStatus[prob.status]
    
    PBallocation = {}
    
    for mach in machines:
        for oper in PBlist:
            if machineList[mach]['stationID'] in PBskills[oper]:
                if PB_ass[(oper,mach)].varValue > 0.00001:
                    PBallocation[oper]=mach
            
    files = glob.glob('*.mps')
    for f in files:
        os.remove(f)
        
    files = glob.glob('*.lp')
    for f in files:
        os.remove(f)
    
    G.totalPulpTime+=time.time()-startPulp
    return PBallocation