def basic_capacitated_node_link(g, demands): """ Creates a basic capacitated network design problem in node-link formulation Parameters ---------- g : networkx.DiGraph a directed network graph g, d : dictionary a dictionary of demands indexed by node pairs Returns ------- pulp.LpProblem a PuLP problem instance suitable for solving or writing. """ # Set up Node Link Formulation Linear Program # First some nice lists to help us stay organized demand_list = sorted(demands.keys()) link_list = sorted(g.edges()) node_list = sorted(g.nodes()) # print demand_list # print link_list # print node_list prob = LpProblem("Basic Node Link Formulation", LpMinimize) # Create a dictionary to hold link flow variables # these will be indexed by a tuple of (link, demand) pairs. # remember that these are each tuples themselves link_flows = {} for link in link_list: for demand in demand_list: name = "D{}_{}_xL{}_{}".format(demand[0], demand[1], link[0], link[1]) link_flows[(link, demand)] = LpVariable(name, 0) # Add the objective function which is the sum of all the # link flow variables times their respective link weights. tmp_list = [] for link in link_list: for demand in demand_list: tmp_list.append(g[link[0]][link[1]]["weight"] * link_flows[(link, demand)]) prob += lpSum(tmp_list) # Now lets include the link capacity constraints # we have one to add for each for link in link_list: tmp_list = [] for demand in demand_list: tmp_list.append(link_flows[(link, demand)]) link_name = "L{}_{}".format(link[0], link[1]) prob += lpSum(tmp_list) <= g[link[0]][ link[1]]['capacity'], "LinkCap|" + link_name # Now for the node flow conservation constraints # We have one of these for each node and demand pair. for node in node_list: for demand in demand_list: tmp_list = [] in_edges = g.in_edges(node) out_edges = g.out_edges(node) for link in out_edges: tmp_list.append(link_flows[(link, demand)]) for link in in_edges: tmp_list.append(-1.0 * link_flows[(link, demand)]) rhs = 0.0 # Default transit node, but check if source or sink if node == demand[0]: # Is node the source of the demand rhs = demands[demand] if node == demand[1]: # Is node the sink of the demand rhs = -demands[demand] constraint_name = "NodeCons|{}D{}_{}".format( node, demand[0], demand[1]) prob += lpSum(tmp_list) == rhs, constraint_name return prob, link_flows
from pulp import LpVariable, LpProblem, LpMaximize, value # -------- INPUT ------------- # Definisikan variabel # x1 maupun x2 tidak boleh bernilai negatif x1 = LpVariable('x1', lowBound=0, cat='Integer') x2 = LpVariable('x2', lowBound=0, cat='Integer') # Definisikan mode maksimum prob = LpProblem('myProblem', LpMaximize) # Definisikan constrain prob += (2 * x1) + x2 <= 400 prob += (2 * x1) + (5 * x2) <= 800 # Definisikan solusi prob += (300 * x1) + (500 * x2) # -------------------------- status = prob.solve() hasil_x1 = int(value(x1)) hasil_x2 = int(value(x2)) maksimal = int(300 * hasil_x1 + 500 * hasil_x2) # Pencetakan print('Kue dadar yang dibuat sebaiknya berjumlah', hasil_x1) print('Kue apem yang dibuat sebaiknya berjumlah', hasil_x2) print('Dengan keuntungan maksimum yang didapat Rp.{}'.format(maksimal))
def add_variable(self, name): return LpVariable(name, cat=LpBinary)
# -*- coding: utf-8 -*- """ Created on Wed Jul 22 16:07:55 2020 @author: Omer """ import pulp from pulp import LpMaximize, LpProblem, LpStatus, lpSum, LpVariable model = LpProblem(name="small-problem", sense=LpMaximize) x = LpVariable(name="x", lowBound=0) y = LpVariable(name="y", lowBound=0) model += (2 * x + y <= 20, "red_cons") model += (4 * x - 5 * y >= -10, "blue_cons") model += (-x + 2 * y >= -2, "yellow_cons") model += (-x + 5 * y == 15, "green_cons") obj_func = x + 2 * y model += obj_func model status = model.solve() model.objective.value() for var in model.variables():
print("g.edges(): ", g.edges()) print("g.nodes(): ", g.nodes()) node_list = list((g.nodes())) node_list = sorted(node_list[0:7]) #print("debug: ",node_list[0]) print("demand_list: ", demand_list) print("link_list; ", link_list) print("node_list: ", node_list) prob = LpProblem("Basic Link Path Formulation", LpMinimize) # Create a dictionary to hold demand path variables # these will be indexed by a tuple of (demand, path_num) pairs. demand_paths = {} for d in demand_list: for p in range(len(paths[d])): name = "xD{}_{}P_{}".format(d[0], d[1], str(p)) demand_paths[d, p] = LpVariable(name, 0) print("demand_paths are: ", demand_paths) # Add the objective function which for now is the sum of all the # demand path variables times their respective path length. tmp_list = [] for d in demand_list: for p in range(len(paths[d])): tmp_list.append((len(paths[d][p]) - 1) * demand_paths[d, p]) prob += lpSum(tmp_list) # Now lets include the link capacity constraints # we have one to add for each lin for link in link_list: tmp_list = [] for d in demand_list: for p in range(len(paths[d])): if link_in_path(link, paths[d][p]):
def setup_variable(self, category, id, min_bound, max_bound): name = '%s_%s' % (category, str(id)) pulpVar = LpVariable(name, min_bound, max_bound, LpInteger) self.pulp_vars[name] = pulpVar
grafo = [[0, 1, 1, 1, 0], [0, 0, 1, 0, 1], [0, 0, 0, 1, 1], [0, 0, 1, 0, 1], [0, 0, 0, 0, 0]] capacidade = [[0, 200, 300, 100, 0], [0, 0, 400, 0, 300], [0, 0, 0, 100, 200], [0, 0, 50, 0, 200], [0, 0, 0, 0, 0]] # Variaveis de decisao var = {} for i in nos: for j in nos: if grafo[i][j] == 1: var[(i, j)] = LpVariable(name=f'x{i}{j}', lowBound=0, cat='Integer') else: continue var.update(var) # Criacao do Modelo model = LpProblem('Problema_fluxo_maximo', LpMaximize) # Funcao objetivo lista_fo = [] for x in var.keys(): if x[0] == no_origem: lista_fo.append(var[x])
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 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) return PBallocation
def optimal_routing_mlu_critical_pairs(self, tm_idx, critical_pairs): tm = self.traffic_matrices[tm_idx] pairs = critical_pairs demands = {} background_link_loads = np.zeros((self.num_links)) for i in range(self.num_pairs): s, d = self.pair_idx_to_sd[i] #background link load if i not in critical_pairs: self.ecmp_next_hop_distribution(background_link_loads, tm[s][d], s, d) else: demands[i] = tm[s][d] model = LpProblem(name="routing") pair_links = [(pr, e[0], e[1]) for pr in pairs for e in self.lp_links] ratio = LpVariable.dicts(name="ratio", indexs=pair_links, lowBound=0, upBound=1) link_load = LpVariable.dicts(name="link_load", indexs=self.links) r = LpVariable(name="congestion_ratio") for pr in pairs: model += (lpSum([ ratio[pr, e[0], e[1]] for e in self.lp_links if e[1] == self.pair_idx_to_sd[pr][0] ]) - lpSum([ ratio[pr, e[0], e[1]] for e in self.lp_links if e[0] == self.pair_idx_to_sd[pr][0] ]) == -1, "flow_convervation_constr1_%d" % pr) for pr in pairs: model += (lpSum([ ratio[pr, e[0], e[1]] for e in self.lp_links if e[1] == self.pair_idx_to_sd[pr][1] ]) - lpSum([ ratio[pr, e[0], e[1]] for e in self.lp_links if e[0] == self.pair_idx_to_sd[pr][1] ]) == 1, "flow_convervation_constr2_%d" % pr) for pr in pairs: for n in self.lp_nodes: if n not in self.pair_idx_to_sd[pr]: model += (lpSum([ ratio[pr, e[0], e[1]] for e in self.lp_links if e[1] == n ]) - lpSum([ ratio[pr, e[0], e[1]] for e in self.lp_links if e[0] == n ]) == 0, "flow_convervation_constr3_%d_%d" % (pr, n)) for e in self.lp_links: ei = self.link_sd_to_idx[e] model += ( link_load[ei] == background_link_loads[ei] + lpSum([demands[pr] * ratio[pr, e[0], e[1]] for pr in pairs]), "link_load_constr%d" % ei) model += (link_load[ei] <= self.link_capacities[ei] * r, "congestion_ratio_constr%d" % ei) model += r + OBJ_EPSILON * lpSum([link_load[ei] for ei in self.links]) model.solve(solver=GLPK(msg=False)) assert LpStatus[model.status] == 'Optimal' obj_r = r.value() solution = {} for k in ratio: solution[k] = ratio[k].value() return obj_r, solution
# -*- coding: utf-8 -*- """ Created on Wed Jan 13 10:34:59 2021 @author: felipecas """ from pulp import LpMaximize, LpProblem, LpStatus, lpSum, LpVariable, GLPK #Create the model model = LpProblem(name = "Wyndor_Glass_Co", sense = LpMaximize) #Initialize the decision variables x1 = LpVariable(name = "x1", lowBound = 0) x2 = LpVariable(name = "x2", lowBound = 0) #Add the constraints to the model model += (x1 <= 4, "Plant 1") model += (2*x2 <= 12, "Plant 2") model += (3*x1 + 2*x2 <= 18, "Plant 3") #Add the objective function to the model model += lpSum([3*x1, 5*x2]) #Solve the problem status = model.solve(solver = GLPK(msg = False)) print(f"Status: {model.status}, {LpStatus[model.status]}") print(f"Objective: {model.objective.value()}") for var in model.variables():
def train_model(warehouse_config_time, current_TIME_QUANTUM, order_sum, wait_pack, p_location, va, vb): upBound_person = 300 index = -1 for i, TIME_QUANTUM, label in warehouse_config_time: if TIME_QUANTUM == current_TIME_QUANTUM: index = i break # assert index!=-1,"当前时间段在配置中找不到" warehouse_config_time = [ e if e[0] >= index else (e[0], e[1], -1) for e in warehouse_config_time ] Xa = [ LpVariable("a%s" % (e[0]), lowBound=0, upBound=upBound_person, cat=pulp.LpInteger) for e in warehouse_config_time ] Xb = [ LpVariable("b%s" % (e[0]), lowBound=0, upBound=upBound_person, cat=pulp.LpInteger) for e in warehouse_config_time ] ###待打包量 Xs = [ LpVariable("s%s" % (e[0]), lowBound=0) for i, e in enumerate(warehouse_config_time) ] opponit_person = LpVariable("opponit_person", lowBound=0, upBound=upBound_person, cat=pulp.LpInteger) sum_ = LpVariable("sum_time", lowBound=0, cat=pulp.LpInteger) z = opponit_person prob = LpProblem('orderperson', LpMinimize) prob += z sum_a = 0 for e in Xa: sum_a += e * va sum_b = 0 for e in Xb: sum_b += e * vb prob += sum_a >= order_sum prob += sum_b >= order_sum + wait_pack que_restrain_index = [e[0] for e in warehouse_config_time if e[2] == 0] que_finish_index = [e[0] for e in warehouse_config_time if e[2] != 0] Xs = [] for e in que_finish_index: Xs.append((e, LpVariable("s%s" % (e), lowBound=0))) for index, e in enumerate(que_restrain_index): if index == len(que_restrain_index) - 1: Xs.append((e, LpVariable("s%s" % (e), lowBound=-vb, upBound=0))) else: Xs.append((e, LpVariable("s%s" % (e), lowBound=-vb))) Xs = [e[1] for e in sorted(Xs, key=lambda x: x[0])] for i in que_finish_index: prob += Xa[i] == 0 prob += Xb[i] == 0 prob += Xs[i] == 0 for index, i in enumerate(que_restrain_index): prob += Xa[i] + Xb[i] <= opponit_person prob += Xb[i] <= p_location if index < len(que_restrain_index) - 1: prob += Xa[que_restrain_index[index]] >= Xa[que_restrain_index[ index + 1]] if index == 0: prob += Xs[i] == wait_pack - Xb[i] * vb else: prob += Xs[i] == Xa[que_restrain_index[ index - 1]] * va - Xb[i] * vb + Xs[que_restrain_index[index] - 1] prob += Xa[que_restrain_index[-1]] == 0 suma = sum(Xa) sumb = sum(Xb) prob += sum_ == suma + sumb status = prob.solve() return status, prob, Xa, Xb
if yr == 0: return payment(x, yr) else: return disc_f[yr - 1] / disc_f[yr] * acc_payments(x, yr - 1) + payment( x, yr) def fund_gap(x, yr): return (acc_payments(x, yr) - liabilities_acc[yr]) / liabilities_NPV[yr] # Model solver: model = LpProblem(name="BondPortfolio", sense=LpMaximize) # variable x = {i: LpVariable(name=f"x{i}", lowBound=0) for i in range(200)} # objective asset_NPV + loaded capital: model += liabilities_NPV[0] - lpSum(cost_vector[i] * x[i] for i in range(200)) # funding gap constraints for i in range(20): model += fund_gap(x, i) <= fg model += fund_gap(x, i) >= -fg # constraints by bond type / tenor model += lpSum(x[j] * sov_mv[j] for j in range(200)) >= 0.075 * lpSum(x[j] * bonds_mv[j] for j in range(200)) model += lpSum(x[j] * sov_mv[j] for j in range(200)) <= 0.33 * lpSum(x[j] * bonds_mv[j]
from pulp import LpProblem, LpVariable, LpMaximize # Initialize Class model = LpProblem("Maximize Glass Co. Profits", LpMaximize) # Define Decision Variables wine = LpVariable('Wine', lowBound=0, upBound=None, cat='Integer') beer = LpVariable('Beer', lowBound=0, upBound=None, cat='Integer') # Define Objective Function model += 5 * wine + 4.5 * beer # Define Constraints model += 6 * wine + 5 * beer <= 60 model += 10 * wine + 20 * beer <= 150 model += wine <= 6 # Solve Model model.solve() print("Produce {} batches of wine glasses".format(wine.varValue)) print("Produce {} batches of beer glasses".format(beer.varValue))
objects = { "stele": (20, 400), "codex": (10, 3000), "manuscript": (5, 2900), "tablet": (3, 50), "slab": (2, 10), "plaque": (8, 150) } extraConstraint1 = False extraConstraint2 = False varTab = {} for obj in objects: varTab[obj] = LpVariable(obj, 0, 1, LpInteger) #the first line added to the problem is the objective objective = [] for obj, (wt, chs) in objects.items(): objective.append((varTab[obj], chs)) problem += LpAffineExpression(objective) constraint = [] for obj, (wt, chs) in objects.items(): constraint.append((varTab[obj], wt)) problem += (LpAffineExpression(constraint) <= 25) if extraConstraint1: problem += varTab["manuscript"] + varTab["codex"] <= 1
def _create_variables(self) -> None: tms = ( self._periods[:-1], self._vehicle_types, range(self._n_scenarios), ) itms = (self._regions, *tms) ijtms = (self._regions, *itms) itmsFull = ( self._regions, self._periods, self._vehicle_types, range(self._n_scenarios), ) self._expected_profit = LpVariable("expected profit", cat=LpContinuous) # trips self._Y = LpVariable.dicts("y", ijtms, lowBound=0, upBound=None, cat=LpInteger) # relocations if not self.relocations_disabled: filtered_ijtms = ( self._regions, self._regions, self._relocation_periods, self._vehicle_types, range(self._n_scenarios), ) self._R = LpVariable.dicts("r", filtered_ijtms, lowBound=0, upBound=None, cat=LpInteger) # vehicle system state self._X_ = LpVariable.dicts("x", itmsFull, lowBound=0, upBound=None, cat=LpInteger) self._X = LpVariable.dicts("x'", itmsFull, lowBound=0, upBound=None, cat=LpInteger) self._V = LpVariable.dicts("v", itmsFull, lowBound=0, upBound=None, cat=LpInteger) # binary variable - no vehicles remain in region self._Vb = LpVariable.dicts("vb", itms, lowBound=0, upBound=1, cat=LpInteger) # unfulfilled demand for region tuple self._U = LpVariable.dicts("u", ijtms, lowBound=0, upBound=None, cat=LpInteger) # unfullfilled demand for region self._bigU = LpVariable.dicts("U", itms, lowBound=0, upBound=None, cat=LpInteger) # binary variable - no unfullfilled demand in regions self._bigUb = LpVariable.dicts("Ub", itms, cat=LpBinary) if self._beta != 0.0: self._eta = LpVariable("value-at-risk", cat=LpContinuous) self._theta = LpVariable.dicts("theta", range(self._n_scenarios), cat=LpBinary)
RESOURCE_USE = [] for m in MACHINES: line = input.readline().split() assert len(line) == NUM_TASKS RESOURCE_USE.append([int(f) for f in line]) line = input.readline().split() assert len(line) == NUM_MACHINES CAPACITIES = [int(f) for f in line] assignVars = [] for m in MACHINES: v = [] for t in TASKS: v.append(LpVariable("M%dT%d" % (m, t), cat=LpBinary)) assignVars.append(v) prob = dippy.DipProblem( "GAP", display_mode='off', layout='dot', display_interval=None, ) # objective prob += lpSum(assignVars[m][t] * COSTS[m][t] for m, t in MACHINES_TASKS), "min" # machine capacity (knapsacks, relaxation) for m in MACHINES: prob.relaxation[m] += lpSum(assignVars[m][t] * RESOURCE_USE[m][t]
def get_best_capped_molecule_with_ILP( molecule: 'Molecule', net_charge: Optional[int] = None, number_hydrogens: Optional[int] = None, enforce_octet_rule: bool = True, allow_radicals: bool = False, debug: Optional[TextIO] = None, ) -> 'Molecule': ''' Use an ILP to cap (complete the valence) of an uncapped molecule using a library a capping fragments. Args: ``molecule``: Molecule to be capped. Some of its atoms should have the ``capped`` attribute set to False. ``net_charge``: (Optional) Constraint the total net charge for the capped molecule. ``number_hydrogens``: (Optional) Constraint the total number of hydrogens for the capped molecule (including hydrogens already present in the molecule). ``enforce_octet_rule``: (Optional) Constraint organic elements (H, C, N, O) to satisfy the octet rule. ``allow_radicals``: (Optional) Allow unpaired non-bonded electrons. ``debug``: (Optional) Print very detailed debugging information Returns: The modified, capped ``molecule``. ''' neighbour_counts = molecule.neighbours_for_atoms() def keep_capping_strategy_for_atom(capping_strategy: Capping_Strategy, atom: Atom) -> bool: if atom.valence is not None: if False: if neighbour_counts[atom.index] + new_atom_for_capping_strategy(capping_strategy) == atom.valence: print(atom, capping_strategy) return neighbour_counts[atom.index] + new_atom_for_capping_strategy(capping_strategy) == atom.valence else: return min_valence_for(atom) <= neighbour_counts[atom.index] + new_atom_for_capping_strategy(capping_strategy) <= max_valence_for(atom) def possible_capping_strategies_for_atom(atom: Atom) -> List[Capping_Strategy]: if debug is not None: write_to_debug(debug, '') write_to_debug(debug, atom) write_to_debug(debug, 'capping_strategy, new_atom_for_capping_strategy(), keep_capping_strategy_for_atom()') for capping_strategy in ALL_CAPPING_OPTIONS[molecule.atom_desc(atom)]: write_to_debug( debug, capping_strategy, new_atom_for_capping_strategy(capping_strategy), keep_capping_strategy_for_atom(capping_strategy, atom) ) return [ capping_strategy for capping_strategy in ALL_CAPPING_OPTIONS[molecule.atom_desc(atom)] if keep_capping_strategy_for_atom(capping_strategy, atom) ] atoms_need_capping = [atom for atom in molecule.sorted_atoms() if not atom.capped] assert len(atoms_need_capping) > 0, 'Error: There are no uncapped atoms in the molecule.' if False: capping_schemes = list( product( *[ possible_capping_strategies_for_atom(atom) for atom in atoms_need_capping ] ), ) assert len(capping_schemes) > 0, [ ( atom, possible_capping_strategies_for_atom(atom), ) for atom in atoms_need_capping if len(possible_capping_strategies_for_atom(atom)) == 0 ] write_to_debug( debug, [ possible_capping_strategies_for_atom(atom) for atom in atoms_need_capping ], ) from pulp import LpProblem, LpMinimize, LpInteger, LpVariable, LpBinary, LpStatus, lpSum problem = LpProblem("Capping problem for molecule {0}".format(molecule.name), LpMinimize) ELECTRON_MULTIPLIER = (2 if not allow_radicals else 1) hydrogens_before_capping = len([1 for atom in molecule.atoms.values() if atom.element == 'H']) counter_charges = {} fragment_switches, fragment_scores, fragment_H_scores = {}, {}, {} capping_atoms_for = {} new_bonds_sets = {} for uncapped_atom in atoms_need_capping: possible_capping_strategies = possible_capping_strategies_for_atom(uncapped_atom) if len(possible_capping_strategies) == 0 or len(possible_capping_strategies) == 1 and possible_capping_strategies[0] == NO_CAP: pass stdout.write('\nWarning: No capping strategy for atom: {0}. The ILP will be infeasible if a suitable cap is not available.'.format(uncapped_atom)) else: for (i, capping_strategy) in enumerate(sorted(possible_capping_strategies), start=1): write_to_debug(debug, uncapped_atom, capping_strategy, i) # Add switch variable fragment_switches[uncapped_atom.index, i] = LpVariable( 'F_{i},{j}'.format(i=uncapped_atom.index, j=i), 0, 1, LpBinary, ) new_atoms, new_bonds = molecule.extend_molecule_with(uncapped_atom, capping_strategy) write_to_debug(debug, i, [atom for atom in new_atoms]) capping_atoms_for[uncapped_atom.index, i] = new_atoms new_bonds_sets[uncapped_atom.index, i] = [bond for bond in new_bonds if uncapped_atom.index in bond] fragment_scores[uncapped_atom.index, i] = len(capping_atoms_for[uncapped_atom.index, i]) fragment_H_scores[uncapped_atom.index, i] = len([atom for atom in capping_atoms_for[uncapped_atom.index, i] if atom.element == 'H']) for capping_atom in new_atoms: # Add counter-charge variable S_i for every atom of the capping strategy counter_charges[capping_atom.index] = LpVariable( "S_{i}".format(i=capping_atom.index), -MAX_ABSOLUTE_CHARGE, MAX_ABSOLUTE_CHARGE, LpInteger, ) problem += (counter_charges[capping_atom.index] <= (1 - fragment_switches[uncapped_atom.index, i]) * MAX_ABSOLUTE_CHARGE, 'Maximum counter charge for capping atom {element}_{index}'.format(element=capping_atom.element, index=capping_atom.index)) problem += (counter_charges[capping_atom.index] >= -(1 - fragment_switches[uncapped_atom.index, i]) * MAX_ABSOLUTE_CHARGE, 'Minimum counter charge for capping atom {element}_{index}'.format(element=capping_atom.element, index=capping_atom.index)) # Only choose one capping strategy at a time problem += (lpSum(F_i for ((atom_id, _), F_i) in fragment_switches.items() if atom_id == uncapped_atom.index) == 1, 'Single capping strategy for atom {element}_{index}'.format(element=uncapped_atom.element, index=uncapped_atom.index)) all_capping_atoms = {atom for atoms in capping_atoms_for.values() for atom in atoms} if True: molecule.write_graph('debug') charges = { atom.index: LpVariable("C_{i}".format(i=atom.index), -MAX_ABSOLUTE_CHARGE, MAX_ABSOLUTE_CHARGE, LpInteger) for atom in molecule.atoms.values() } original_charges = list(charges.values()) # Extra variable use to bind charges absolute_charges = { atom_id: LpVariable("Z_{i}".format(i=atom_id), MIN_ABSOLUTE_CHARGE, MAX_ABSOLUTE_CHARGE, LpInteger) for atom_id in charges.keys() } non_bonded_electrons = { atom_id: LpVariable("N_{i}".format(i=atom_id), 0, MAX_NONBONDED_ELECTRONS // ELECTRON_MULTIPLIER, LpInteger) for (atom_id, atom) in molecule.atoms.items() } # Maps a bond to an integer bond_mapping = { bond: i for (i, bond) in enumerate(molecule.bonds) } # Maps an integer to a bond bond_reverse_mapping = {v: k for (k, v) in bond_mapping.items()} bond_key = lambda bond: ','.join(map(str, sorted(bond))) bond_orders = { bond: LpVariable( "B_{bond_key}".format(bond_key=bond_key(bond)), 0 if any(bond in new_bonds for new_bonds in new_bonds_sets.values()) else MIN_BOND_ORDER, MAX_BOND_ORDER, LpInteger, ) for bond in molecule.bonds } for ((uncapped_atom_id, i), new_bonds) in new_bonds_sets.items(): for new_bond in new_bonds: problem += (bond_orders[new_bond] >= fragment_switches[uncapped_atom_id, i], 'Minimum bond order for fragment bond {bond_key}'.format(bond_key=bond_key(new_bond))) problem += (bond_orders[new_bond] <= MAX_BOND_ORDER * fragment_switches[uncapped_atom_id, i], 'Maximum bond order for fragment bond {bond_key}'.format(bond_key=bond_key(new_bond))) OBJECTIVES = [ MIN(lpSum(absolute_charges.values())), ] H_size_objective = MAX(lpSum([F_i * fragment_H_scores[uncapped_atom_id, i] for ((uncapped_atom_id, i), F_i) in fragment_switches.items()])) has_non_null_H_size_objective = (sum([fragment_H_scores[uncapped_atom_id, i] for ((uncapped_atom_id, i), F_i) in fragment_switches.items()]) != 0) if has_non_null_H_size_objective: OBJECTIVES.append(H_size_objective) total_size_objective = MIN(lpSum([F_i * fragment_scores[uncapped_atom_id, i] for ((uncapped_atom_id, i), F_i) in fragment_switches.items()])) if sum([fragment_scores[uncapped_atom_id, i] for ((uncapped_atom_id, i), F_i) in fragment_switches.items()]) != 0: OBJECTIVES.append(total_size_objective) OBJECTIVES.extend([ MIN(lpSum([charge * ELECTRONEGATIVITIES[molecule.atoms[atom_id].element] for (atom_id, charge) in charges.items()])), MIN(lpSum([bond_order * ELECTRONEGATIVITIES[molecule.atoms[atom_id].element] for (bond, bond_order) in bond_orders.items() for atom_id in bond])), ]) if net_charge is not None: problem += (lpSum(charges.values()) == net_charge, 'Known net charge') if number_hydrogens is not None: problem += ( lpSum( [ F_i * fragment_H_scores[uncapped_atom_id, i] for ((uncapped_atom_id, i), F_i) in fragment_switches.items() ], ) + hydrogens_before_capping == number_hydrogens, 'Total number of hydrogens: {0}'.format(number_hydrogens) ) for atom in molecule.atoms.values(): problem += ( charges[atom.index] == VALENCE_ELECTRONS[atom.element] - lpSum([bond_orders[bond] for bond in molecule.bonds if atom.index in bond]) - ELECTRON_MULTIPLIER * non_bonded_electrons[atom.index] - (counter_charges[atom.index] if atom.index in counter_charges else 0) , 'Electron balance for atom {element}_{index}'.format(element=atom.element, index=atom.index), ) # Deal with absolute values for atom in molecule.atoms.values(): problem += charges[atom.index] <= absolute_charges[atom.index], 'Absolute charge contraint 1 {i}'.format(i=atom.index) problem += -charges[atom.index] <= absolute_charges[atom.index], 'Absolute charge contraint 2 {i}'.format(i=atom.index) if enforce_octet_rule and atom not in all_capping_atoms: if atom.element not in {'B', 'BE', 'P', 'S'}: problem += ( ELECTRONS_PER_BOND * lpSum([bond_orders[bond] for bond in molecule.bonds if atom.index in bond]) + ELECTRON_MULTIPLIER * non_bonded_electrons[atom.index] == (2 if atom.element in {'H', 'HE'} else 8), 'Octet for atom {element}_{index}'.format(element=atom.element, index=atom.index), ) try: problem.sequentialSolve(OBJECTIVES, timeout=ILP_SOLVER_TIMEOUT) assert problem.status == 1, (molecule.name, LpStatus[problem.status]) #assert False except Exception as e: problem.writeLP('debug.lp') molecule.write_graph('DEBUG', output_size=(1000, 1000)) print('Failed LP written to "debug.lp"') raise DELETE_FAILED_CAPS = True molecule.formal_charges, molecule.bond_orders, molecule.non_bonded_electrons = {}, {}, {} atoms_to_remove = set() for v in problem.variables(): variable_type, variable_substr = v.name.split('_') if variable_type == 'C': atom_index = int(variable_substr) molecule.formal_charges[atom_index] = MUST_BE_INT(v.varValue) elif variable_type == 'B': if False: bond_index = int(variable_substr) molecule.bond_orders[bond_reverse_mapping[bond_index]] = MUST_BE_INT(v.varValue) else: bond = frozenset(map(int, variable_substr.split(','))) molecule.bond_orders[bond] = MUST_BE_INT(v.varValue) elif variable_type == 'Z': pass elif variable_type == 'N': atom_index = int(variable_substr) molecule.non_bonded_electrons[atom_index] = MUST_BE_INT(v.varValue) * ELECTRON_MULTIPLIER elif variable_type == 'F': uncapped_atom_id, capping_strategy_id = map(int, variable_substr.split(',')) if MUST_BE_INT(v.varValue) == 0 and DELETE_FAILED_CAPS: atoms_to_remove.add((uncapped_atom_id, capping_strategy_id)) elif variable_type == 'S': capping_atom_id = int(variable_substr) else: raise Exception('Unknown variable type: {0}'.format(variable_type)) if DELETE_FAILED_CAPS: for (uncapped_atom_id, capping_strategy_id) in atoms_to_remove: molecule.remove_atoms(atom for atom in capping_atoms_for[uncapped_atom_id, capping_strategy_id]) if not allow_radicals and False: assert all([nonbonded_electrons % 2 == 0 for nonbonded_electrons in molecule.non_bonded_electrons.values()]), { molecule.atoms[atom_index]: electrons for (atom_index, electrons) in molecule.non_bonded_electrons.items() if electrons % 2 == 1 } molecule.update_valences() molecule.assign_aromatic_bonds() molecule.assert_molecule_coherence() return molecule
# transport_types = introduceProblem.introduce_truck_types() selling_cost = introduceProblem.introduce_selling_cost( depreciation_rate, buying_price_1, buying_price_2) # cost[type][age] requests = introduceProblem.introduce_city_requests() # cities_list = ["Anvers", "Charleroi", "Gand", "Bruxelles", "Hasselt", "Liege"] cities_number = 5 # On ne compte pas Liège # Initialisation ################### print("Initialisation") problem = LpProblem(name="Projet", sense=LpMinimize) n1 = [[[ LpVariable('n1_{},{},{}'.format(p, v, s), cat='Integer', lowBound=0) for s in range(semester_number) ] for v in range(cities_number)] for p in [0, 1]] # n1_pvs n2 = [ [0] + [[[ LpVariable( 'n2_{},{},{},{}'.format(p, v, s, a), cat='Integer', lowBound=0) for a in [0, 1] ] for s in range(semester_number)] for v in range(1, cities_number)] # Ne peut pas être dans anvers for p in [0, 1] ] # n2_pvsa
def ilp_cgdp( cg: ComputationGraph, agentsdef: Iterable[AgentDef], footprint: Callable[[str], float], capacity: Callable[[str], float], route: Callable[[str, str], float], msg_load: Callable[[str, str], float], hosting_cost: Callable[[str, str], float], ): agt_names = [a.name for a in agentsdef] pb = LpProblem("oilp_cgdp", LpMinimize) # One binary variable xij for each (variable, agent) couple xs = LpVariable.dict("x", (cg.node_names(), agt_names), cat=LpBinary) # TODO: Do not create var for computation that are already assigned to an agent with hosting = 0 ? # Force computation with hosting cost of 0 to be hosted on that agent. # This makes the work much easier for glpk ! x_fixed_to_0 = [] x_fixed_to_1 = [] for agent in agentsdef: for comp in cg.node_names(): assigned_agent = None if agent.hosting_cost(comp) == 0: pb += xs[(comp, agent.name)] == 1 x_fixed_to_1.append((comp, agent.name)) assigned_agent = agent.name for other_agent in agentsdef: if other_agent.name == assigned_agent: continue pb += xs[(comp, other_agent.name)] == 0 x_fixed_to_0.append((comp, other_agent.name)) logger.debug( f"Setting binary varaibles to fixed computation {comp}") # One binary variable for computations c1 and c2, and agent a1 and a2 betas = {} count = 0 for a1, a2 in combinations(agt_names, 2): # Only create variables for couple c1, c2 if there is an edge in the # graph between these two computations. for l in cg.links: # As we support hypergraph, we may have more than 2 ends to a link for c1, c2 in combinations(l.nodes, 2): if (c1, a1, c2, a2) in betas: continue count += 2 b = LpVariable("b_{}_{}_{}_{}".format(c1, a1, c2, a2), cat=LpBinary) betas[(c1, a1, c2, a2)] = b # Linearization constraints : # a_ijmn <= x_im # a_ijmn <= x_jn if (c1, a1) in x_fixed_to_0 or (c2, a2) in x_fixed_to_0: pb += b == 0 elif (c1, a1) in x_fixed_to_1: pb += b == xs[(c2, a2)] elif (c2, a2) in x_fixed_to_1: pb += b == xs[(c1, a1)] else: pb += b <= xs[(c1, a1)] pb += b <= xs[(c2, a2)] pb += b >= xs[(c2, a2)] + xs[(c1, a1)] - 1 b = LpVariable("b_{}_{}_{}_{}".format(c1, a2, c2, a1), cat=LpBinary) if (c1, a2) in x_fixed_to_0 or (c2, a1) in x_fixed_to_0: pb += b == 0 elif (c1, a2) in x_fixed_to_1: pb += b == xs[(c2, a1)] elif (c2, a1) in x_fixed_to_1: pb += b == xs[(c1, a2)] else: betas[(c1, a2, c2, a1)] = b pb += b <= xs[(c2, a1)] pb += b <= xs[(c1, a2)] pb += b >= xs[(c1, a2)] + xs[(c2, a1)] - 1 # Set objective: communication + hosting_cost pb += ( _objective(xs, betas, route, msg_load, hosting_cost), "Communication costs and prefs", ) # Adding constraints: # Constraints: Memory capacity for all agents. for a in agt_names: pb += ( lpSum([footprint(i) * xs[i, a] for i in cg.node_names()]) <= capacity(a), "Agent {} capacity".format(a), ) # Constraints: all computations must be hosted. for c in cg.node_names(): pb += ( lpSum([xs[c, a] for a in agt_names]) == 1, "Computation {} hosted".format(c), ) # solve using GLPK status = pb.solve( solver=GLPK_CMD(keepFiles=1, msg=False, options=["--pcost"])) if status != LpStatusOptimal: raise ImpossibleDistributionException("No possible optimal" " distribution ") logger.debug("GLPK cost : %s", pulp.value(pb.objective)) mapping = {} for k in agt_names: agt_computations = [ i for i, ka in xs if ka == k and pulp.value(xs[(i, ka)]) == 1 ] # print(k, ' -> ', agt_computations) mapping[k] = agt_computations return mapping
# productは直積を作る関数 # 二つの変数が取るすべての組み合わせを作る pr = list(product(range(nw), range(nf))) print(nw) print(nf) print(pr) # In[9]: # 数理モデル作成 # m1 = model_min() v1 = {(i,j):LpVariable('v%d_%d'%(i,j),lowBound=0) for i,j in pr} # (x,x)というタプル型でアクセス出来るようにする print(v1) # In[10]: m1 += lpSum(df_tc.iloc[i][j]*v1[i,j] for i,j in pr) # コストの足し上げ for i in range(nw): m1 += lpSum(v1[i,j] for j in range(nf)) <= df_supply.iloc[0][i] for j in range(nf):
import numpy as np from pulp import LpProblem, LpVariable, lpSum A = np.array([[1, 0], [0, 1]]) b = np.array([1, 1]) c = np.array([1, 1]) # 主問題 primal_model = LpProblem(sense=LpMaximize) x = [LpVariable(f'x{i}', lowBound=0) for i in range(2)] primal_model += lpSum(c.T * x) for row, rhs in zip(A, b): primal_model += lpSum(row * x) <= rhs
#2点間の距離を算出する def dist(p1, p2): return (sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2) / SIZE) ######変数定義 #どこにPointを置くか x = LpVariable.dict(name="x", indexs=(range(SIZE), range(SIZE)), lowBound=0, upBound=1, cat=LpBinary) #今回のキモ 多目的のための変数(どんなに良くても対角の√2以下) z = LpVariable("z", lowBound=0, upBound=1.5, cat=LpContinuous) #問題定義 p = LpProblem(name="SpreadingPointsProblem", sense=LpMaximize) #zの最大化問題として定義 p += z #N個のPointが配置される tmp_sub = 0 for i, j in product(range(SIZE), range(SIZE)): tmp_sub += x[(i, j)] p += tmp_sub == N #確認した2点に同時に点が配置されているとしたばあい、その距離はz以上 BIGM = 100.0
def generate_data_for_selectivity(self, selectivity, n_tuples): """ NOTE: This is currently unused. Not even sure if I completed it. But give a look at it again because there were some interesting ideas. """ def generate_valid_and_invalid_subsets(n_vars, n_subsets, n_valid): # TODO: Read again this function. There's some interesting logic n_subsets = int(math.ceil(n_subsets)) n_valid = int(math.ceil(n_valid)) assert n_valid <= n_subsets == 2**n_vars valid = [] invalid = [] # This must be always valid (it is the sum of no tuples) # valid.append( (0,)*n_vars ) valid.append(0) # Generate half of vars valid and half invalid for i in range(n_vars): if len(valid) < n_valid / 2.: # valid.append(tuple( bit for bit in ('{:0%dbms}' % n_tuples).format(2**i) )) valid.append(2**i) elif len(invalid) < (n_subsets - n_valid) / 2.: # invalid.append(tuple( bit for bit in ('{:0%dbms}' % n_tuples).format(2**i) )) invalid.append(2**i) else: valid.append(2**i) # Generate more invalid (up to n_subsets-n_valid) by combining invalid + invalid while len(invalid) < n_subsets - n_valid: found = False for i in range(len(invalid)): for j in range(len(invalid)): new_invalid = invalid[i] | invalid[j] if new_invalid not in invalid: invalid.append(new_invalid) found = True break if found: break if not found: break # If more invalid are needed, generate them by combining invalid + valid while len(invalid) < n_subsets - n_valid: found = False for i in range(len(invalid)): for j in range(len(valid)): new_invalid = invalid[i] | valid[j] if new_invalid not in invalid: invalid.append(new_invalid) found = True break if found: break if not found: raise Exception # All the remaining ones are valid valid = set(range(n_subsets)) - set(invalid) assert len(valid) == n_valid assert len(valid) + len(invalid) == n_subsets if logging.getLogger().getEffectiveLevel() == logging.DEBUG: debug("n invalid = {}".format(n_subsets - n_valid)) debug("{}".format(valid)) debug("{}".format(invalid)) debug("{}".format([ tuple(bit for bit in ('{:0%dbms}' % n_tuples).format(i)) for i in valid ])) debug("{}".format([ tuple(bit for bit in ('{:0%dbms}' % n_tuples).format(i)) for i in invalid ])) return valid, invalid def generate_set_of_problems(base_prob, vars, total_n_constraints, n_valid_constraints, a, b): problems = [] for valid in itertools.combinations( range(total_n_constraints), int(math.ceil(n_valid_constraints))): valid = set(valid) invalid = set(range(total_n_constraints)) - valid assert set(valid) | invalid == set(range(total_n_constraints)) # The empty package must always be valid. TODO: Really? # valid = [0] + list(valid) prob = base_prob.copy() # valid = generate_valid_and_invalid_subsets(n_tuples, total_n_constraints, n_valid_constraints)[0] # valid = np.random.choice(range(total_n_constraints), size=n_valid_constraints, replace=False) if logging.getLogger().getEffectiveLevel() == logging.DEBUG: debug("VALID: {}".format(valid)) debug("INVALID: {}".format( sorted(set(range(total_n_constraints)) - set(valid)))) # Add valid constraints to the problem n_valid_added = 0 for i in valid: package_bitmap = [ int(bit) for bit in ('{:0%dbms}' % n_tuples).format(i) ] assert len(package_bitmap) == len(vars) # Add a VALID constraint for this combination of tuples prob += np.dot(vars, package_bitmap) >= a prob += np.dot(vars, package_bitmap) <= b n_valid_added += 1 assert n_valid_added == len(valid) # Add invalid constraints to the problem n_invalid_added = 0 if float(a) > -float("inf") and float(b) < float("inf"): # In this case, we produce 2**(len(invalid)) new sub-problems, each for a different set of ways # to break the constraints a <= sum() <= b pairs_of_invalid_constraints = [] for i in invalid: package_bitmap = [ int(bit) for bit in ('{:0%dbms}' % n_tuples).format(i) ] pairs_of_invalid_constraints.append(( (package_bitmap, operator.le, a - 1), (package_bitmap, operator.ge, b + 1), )) orig_prob = prob.copy() for set_of_invalid in itertools.product( *pairs_of_invalid_constraints): new_prob = orig_prob.copy() for invalid_bitmap, op, c in set_of_invalid: new_prob += op(np.dot(vars, invalid_bitmap), c) problems.append(new_prob) else: # In this case, we only generate one sub-problem by adding all invalid constraints for i in invalid: package_bitmap = [ int(bit) for bit in ('{:0%dbms}' % n_tuples).format(i) ] assert len(package_bitmap) == len(vars) # Add an INVALID (out of range) constraint for this combination of tuples if float(a) > -float("inf") and float(b) < float( "inf"): raise Exception("Should never happen!") # prob += np.dot(vars, package_bitmap) <= a-1 elif float(a) > -float("inf"): prob += np.dot(vars, package_bitmap) <= a - 1 elif float(b) < float("inf"): prob += np.dot(vars, package_bitmap) >= b + 1 else: raise Exception assert n_invalid_added == len(invalid) problems.append(prob) return problems assert 0 <= selectivity <= 1 assert n_tuples >= 0 table_name_start = self.bc_query.lower().find("from ") table_name_end = self.bc_query[table_name_start + 5:].lower().find(" ") table_name = self.bc_query[table_name_start + 5:table_name_start + 5 + table_name_end] attribute_names = [] ranges = [] for j in range(len(self.gc_queries)): if 'sum(' in self.gc_queries[j].lower(): attr_start = self.gc_queries[j].lower().find('sum(') attr_end = self.gc_queries[j][attr_start + 4:].lower().find(')') attribute_names.append( self.gc_queries[j][attr_start + 4:attr_start + 4 + attr_end]) ranges.append(self.gc_ranges[j]) debug("{} {}".format(attribute_names, ranges)) assert len(attribute_names) == len(ranges) # Generate the data via CPLEX data_columns = [] # Generate one column at a time. Each column is generated with a CPLEX problem for j in range(len(attribute_names)): a, b = ranges[j] total_n_constraints = 2**n_tuples n_valid_constraints = (1 - selectivity) * total_n_constraints # Check satisfiability of requirements if n_valid_constraints == 0 and a <= 0 <= b: warning( "Since a<=0<=b there is always at least one valid package, i.e. the empty package, " "therefore selectivity=1 (where no package is valid) is impossible." ) return None if n_valid_constraints == total_n_constraints and not a <= 0 <= b: warning( "Since not a<=0<=b, the empty package may never be a valid package, " "therefore selectivity=0 (where all packages are valid) is impossible." ) return None # Create the base problem base_prob = LpProblem("package-builder", LpMinimize) base_prob += 0 # no objective # Add constraints to the problem vars = [ LpVariable("{}_{}".format(attribute_names[j], i), -float("inf"), float("inf"), LpInteger) for i in range(n_tuples) ] # Generate all possible combination of problem constraints # One of them will be feasible and will give us the dataset problems = generate_set_of_problems(base_prob, vars, total_n_constraints, n_valid_constraints, a, b) # Now try to find one feasible problem for prob in problems: # Solve the problem debug("{}".format(prob)) solver = CPLEX(msg=True, timeLimit=None) solver.solve(prob) # Check the problem status if LpStatus[prob.status] == 'Infeasible': debug("@@@@@@@@@@@@@@@@@ INFEASIBLE: CONTINUE") continue elif LpStatus[prob.status] == 'Undefined': raise Exception("Problem is undefined.") elif LpStatus[prob.status] == 'Optimal': debug("################## OPTIMAL") prob.roundSolution() sol = [ v.varValue for v in prob.tuple_variables() if type(v.varValue) is float ] data_columns.append(sol) break else: raise Exception("LP status: {}".format( LpStatus[prob.status])) else: raise Exception( "Could not find feasible combination of constraints " "for selectivity {} and {} tuples.".format( selectivity, n_tuples)) tuples = np.array(data_columns).transpose() return table_name, attribute_names, tuples
def getGraphFromDegrees(degrees): #numberOfEdges = sum(degrees) / 2 numberOfVertices = len(degrees) prob = LpProblem("THE_GRAPH_CREATING_PROBLEM", LpMinimize) # vertices variables verticesVariables = [] for vv in range(1, numberOfVertices + 1): vertVar = LpVariable("VERTEX_" + str(vv), 1, numberOfVertices - 1, LpInteger) prob += vertVar == degrees[vv - 1] verticesVariables.append(vertVar) # edge variables edgeVariables = {} edgeVariablesForOverlap = {} for i in range(1, numberOfVertices + 1): for j in range(i + 1, numberOfVertices + 1): # print(i, " -- ", j) edgeVar = LpVariable("EDGE_" + str(i) + "-" + str(j), 0, 1, LpInteger) if i not in edgeVariables.keys(): edgeVariables[i] = [edgeVar] else: edgeVariables[i].append(edgeVar) if j not in edgeVariables.keys(): edgeVariables[j] = [edgeVar] else: edgeVariables[j].append(edgeVar) if i not in edgeVariablesForOverlap.keys(): edgeVariablesForOverlap[i] = {} if j not in edgeVariablesForOverlap[i].keys(): edgeVariablesForOverlap[i][j] = edgeVar if j not in edgeVariablesForOverlap.keys(): edgeVariablesForOverlap[j] = {} if i not in edgeVariablesForOverlap[j].keys(): edgeVariablesForOverlap[j][i] = edgeVar for i in edgeVariables: prob += lpSum(edgeVariables[i]) == verticesVariables[i - 1] # overlaps overlapVars = [] for fst, lst in getOverlapEdgePairs(numberOfVertices): #print(fst, lst) # now we get the edgeVars respectively fstEdgeVar = edgeVariablesForOverlap[fst[0] + 1][fst[1] + 1] lstEdgeVar = edgeVariablesForOverlap[lst[0] + 1][lst[1] + 1] # print(fstEdgeVar) # print(lstEdgeVar) overlapVar = LpVariable("OVERLAP_" + str(fst) + "-" + str(lst), 0, 1, LpInteger) prob += overlapVar >= fstEdgeVar + lstEdgeVar - 1 overlapVars.append(overlapVar) # print() # objective function: minimize the overlaps prob += sum(overlapVars) # print("Solving...") prob.solve() statusText = LpStatus[prob.status] # print("Status:", statusText) if statusText == "Optimal": returner = [] for v in prob.variables(): if v.varValue != 0: # print(v.name, "=", v.varValue) varNameSplit = v.name.split("_") if varNameSplit[0] == "EDGE": returner.append( [int(varNameSplit[1]), int(varNameSplit[2])]) return returner return None
def makeMatrixElementsPositive(payMatrix, minElement): for i in range(len(payMatrix)): for j in range(len(payMatrix[i])): payMatrix[i][j] = payMatrix[i][j] + abs(minElement) return payMatrix "Task1" print("Task1") # Point1 print("Point1") #создаём модель model = LpProblem(name="Task1Lol1", sense=LpMinimize) # Описываем переменные x = {i: LpVariable(name=f"x{i}", lowBound=0) for i in range(0, 3)} # Добавляем ограничения model += (14 * x[0] + 15 * x[1] + 33 * x[2] >= 1, "First") model += (20 * x[0] + 11 * x[1] + 9 * x[2] >= 1, "Second") model += (32 * x[0] + 19 * x[1] + 16 * x[2] >= 1, "Third") model += (8 * x[0] + 37 * x[1] + 34 * x[2] >= 1, "Fourth") # Описываем цель model += x[0] + x[1] + x[2] # Решаем задачу оптимизации status = model.solve() # Выводим результаты решения print(f"status: {model.status}, {LpStatus[model.status]}") print(f"objective: {model.objective.value()}") pFirstPlayer = [0] * 3 counter = 0
def __approximate_alignment_on_loop(pt: ProcessTree, trace: Trace, pt_a_set: Dict[ProcessTree, Set[str]], pt_sa_set: Dict[ProcessTree, Set[str]], pt_ea_set: Dict[ProcessTree, Set[str]], pt_tau_flag: Dict[ProcessTree, bool], tl: int, th: int): assert pt.operator == Operator.LOOP assert len(pt.children) == 2 assert len(trace) > 0 ilp = LpProblem("splitting_trace_and_assign_to_subtrees", LpMinimize) # ilp.solve(solvers.GUROBI_CMD()) # x_i_j = 1 <=> assigns activity i to subtree j x_variables: Dict[int, Dict[int, LpVariable]] = {} # t_i_j = 1 <=> inserts a tau at position i and assigns it to subtree j t_variables: Dict[int, Dict[int, LpVariable]] = {} # s_i_j = 1 <=> activity i is a start activity in the current sub-trace assigned to subtree j s_variables: Dict[int, Dict[int, LpVariable]] = {} # e_i_j = 1 <=> activity i is an end activity in the current sub-trace assigned to subtree j e_variables: Dict[int, Dict[int, LpVariable]] = {} # v_i_j = 1 <=> activity i is neither a start nor end-activity in the current sub-trace assigned to subtree j v_variables: Dict[int, Dict[int, LpVariable]] = {} # auxiliary variables # p_i_j = 1 <=> previous activity i-1 is assigned to the other subtree or t_1_other-subtree is 1 p_variables: Dict[int, Dict[int, LpVariable]] = {} # n_i_j = 1 <=> next activity i+1 is assigned to the other subtree or t_1_other-subtree is 1 n_variables: Dict[int, Dict[int, LpVariable]] = {} t_costs = {} s_costs = {} e_costs = {} v_costs = {} # trace <a_0,...,a_n> for i, a in enumerate(trace): x_variables[i] = {} s_variables[i] = {} s_costs[i] = {} e_variables[i] = {} e_costs[i] = {} v_variables[i] = {} v_costs[i] = {} p_variables[i] = {} n_variables[i] = {} for j, subtree in enumerate(pt.children): x_variables[i][j] = LpVariable('x_' + str(i) + '_' + str(j), cat='Binary') s_variables[i][j] = LpVariable('s_' + str(i) + '_' + str(j), cat='Binary') s_costs[i][ j] = 0 if a[DEFAULT_NAME_KEY] in pt_sa_set[subtree] else 1 e_variables[i][j] = LpVariable('e_' + str(i) + '_' + str(j), cat='Binary') e_costs[i][ j] = 0 if a[DEFAULT_NAME_KEY] in pt_ea_set[subtree] else 1 v_variables[i][j] = LpVariable('v_' + str(i) + '_' + str(j), cat='Binary') v_costs[i][ j] = 0 if a[DEFAULT_NAME_KEY] in pt_a_set[subtree] else 1 p_variables[i][j] = LpVariable('p_' + str(i) + '_' + str(j), cat='Binary') n_variables[i][j] = LpVariable('n_' + str(i) + '_' + str(j), cat='Binary') for i in range(len(trace) + 1): t_variables[i] = {} t_costs[i] = {} for j, subtree in enumerate(pt.children): t_variables[i][j] = LpVariable('t_' + str(i) + '_' + str(j), cat='Binary') if pt_tau_flag[subtree]: t_costs[i][j] = 0 else: if len(pt_sa_set[subtree].intersection( pt_ea_set[subtree])) != 0: t_costs[i][j] = 1 else: t_costs[i][j] = 2 # objective function ilp += lpSum([ s_variables[i][j] * s_costs[i][j] for i in range(len(trace)) for j in range(len(pt.children)) ] + [ e_variables[i][j] * e_costs[i][j] for i in range(len(trace)) for j in range(len(pt.children)) ] + [ v_variables[i][j] * v_costs[i][j] for i in range(len(trace)) for j in range(len(pt.children)) ] + [ t_variables[i][j] * t_costs[i][j] for i in range(len(trace) + 1) for j in range(len(pt.children)) ]), "objective_function" # constraints # universe j {0,1} # universe i for t_i_j variables {0,...,len(trace)} # universe i else {0,...,len(trace)-1} # first tau can never be assigned to the 2nd subtree ilp += t_variables[0][1] == 0 # last tau can never be assigned to the 2nd subtree ilp += t_variables[len(trace)][1] == 0 # if first/last tau is not used --> first/last activity is assigned to 1st subtree ilp += 1 - t_variables[0][0] <= x_variables[0][0] ilp += 1 - t_variables[len(trace)][0] <= x_variables[len(trace) - 1][0] for i in range(len(trace)): # every activity is assigned to one subtree ilp += lpSum([x_variables[i][j] * 1 for j in range(len(pt.children))]) == 1 # start/end/intermediate-activity at position i can only be assigned to one subtree ilp += lpSum([s_variables[i][j] * 1 for j in range(len(pt.children))]) <= 1 ilp += lpSum([e_variables[i][j] * 1 for j in range(len(pt.children))]) <= 1 ilp += lpSum([v_variables[i][j] * 1 for j in range(len(pt.children))]) <= 1 for i in range(len(trace) + 1): # max one tau is used per index ilp += lpSum([t_variables[i][j] for j in range(2)]) <= 1 # if tau is used and hence, assigned to a subtree, the surrounding activities are assigned to the other subtree for i in range(1, len(trace)): # if tau at position i is assigned to 1st subtree, the previous activity is assigned to 2nd subtree ilp += t_variables[i][0] <= x_variables[i - 1][1] # if tau at position i is assigned to 1st subtree, the previous activity is assigned to 2nd subtree ilp += t_variables[i][1] <= x_variables[i - 1][0] for i in range(len(trace)): # if tau at position i is assigned to 1st subtree, the next activity is assigned to 2nd subtree ilp += t_variables[i][0] <= x_variables[i][1] # if tau at position i is assigned to 2nd subtree, the next activity is assigned to 1st subtree ilp += t_variables[i][1] <= x_variables[i][0] # if last tau is used and assigned to 1st subtree (assigning it to the 2nd subtree is already forbidden by another # constraint) --> last activity must be assigned to 2nd subtree ilp += t_variables[len(trace)][0] <= x_variables[len(trace) - 1][1] # define auxiliary variables n: n_i_1 = 1 <=> next activity i+1 is assigned to 2nd subtree or t_i+1_2 = 1 for i in range(len(trace) - 1): ilp += n_variables[i][0] <= x_variables[i + 1][1] + t_variables[i + 1][1] ilp += n_variables[i][0] >= x_variables[i + 1][1] ilp += n_variables[i][0] >= t_variables[i + 1][1] ilp += n_variables[i][1] <= x_variables[i + 1][0] + t_variables[i + 1][0] ilp += n_variables[i][1] >= x_variables[i + 1][0] ilp += n_variables[i][1] >= t_variables[i + 1][0] ilp += t_variables[len(trace)][1] <= n_variables[len(trace) - 1][0] ilp += t_variables[len(trace)][0] <= n_variables[len(trace) - 1][1] # define e_i_j variables for i in range(len(trace)): for j in range(2): ilp += e_variables[i][j] <= n_variables[i][j] ilp += e_variables[i][j] <= x_variables[i][j] ilp += e_variables[i][ j] >= n_variables[i][j] + x_variables[i][j] - 1 # define auxiliary variables p: p_i_1 = 1 <=> previous activity i-1 is assigned to 2nd subtree or t_i-1_2 = 1 ilp += t_variables[0][1] <= p_variables[0][0] ilp += p_variables[0][1] <= t_variables[0][0] for i in range(1, len(trace)): ilp += p_variables[i][0] <= t_variables[i][1] + x_variables[i - 1][1] ilp += p_variables[i][0] >= t_variables[i][1] ilp += p_variables[i][0] >= x_variables[i - 1][1] ilp += p_variables[i][1] <= t_variables[i][0] + x_variables[i - 1][0] ilp += p_variables[i][1] >= t_variables[i][0] ilp += p_variables[i][1] >= x_variables[i - 1][0] # define s_i_j variables for i in range(len(trace)): for j in range(2): ilp += s_variables[i][ j] >= p_variables[i][j] + x_variables[i][j] - 1 ilp += s_variables[i][j] <= p_variables[i][j] ilp += s_variables[i][j] <= p_variables[i][j] ilp += 1 - t_variables[0][0] <= s_variables[0][0] # define v_i_j variables for i in range(len(trace)): for j in range(2): ilp += v_variables[i][j] >= 1 - s_variables[i][ j] + 1 - e_variables[i][j] + x_variables[i][j] - 2 ilp += v_variables[i][j] <= x_variables[i][j] ilp += v_variables[i][j] <= 1 - e_variables[i][j] ilp += v_variables[i][j] <= 1 - s_variables[i][j] status = ilp.solve() logging.debug("LP status: " + str(status)) assert status == 1 # LpStatusOptimal “Optimal” 1 # LpStatusNotSolved “Not Solved” 0 # LpStatusInfeasible “Infeasible” -1 # LpStatusUnbounded “Unbounded” -2 # LpStatusUndefined “Undefined” -3 # DEBUG code # logging.debug('Trace length: ' + str(len(trace))) # trace_str = "\t\t\t" # for e in trace: # trace_str += e['concept:name'] + "\t\t\t\t\t" # x_str_j_1 = "\t\t\t" # x_str_j_2 = "\t\t\t" # # s_str_j_1 = "\t\t\t" # s_str_j_2 = "\t\t\t" # # e_str_j_1 = "\t\t\t" # e_str_j_2 = "\t\t\t" # # n_str_j_1 = "\t\t\t" # n_str_j_2 = "\t\t\t" # # p_str_j_1 = "\t\t\t" # p_str_j_2 = "\t\t\t" # # v_str_j_1 = "\t\t\t" # v_str_j_2 = "\t\t\t" # # t_str_j_1 = "" # t_str_j_2 = "" # # for i in range(len(trace)): # x_str_j_1 += "x_" + str(i) + "_" + "0" + ": " + str(int(x_variables[i][0].varValue)) + "\t\t\t" # x_str_j_2 += "x_" + str(i) + "_" + "1" + ": " + str(int(x_variables[i][1].varValue)) + "\t\t\t" # s_str_j_1 += "s_" + str(i) + "_" + "0" + ": " + str(int(s_variables[i][0].varValue)) + "\t\t\t" # s_str_j_2 += "s_" + str(i) + "_" + "1" + ": " + str(int(s_variables[i][1].varValue)) + "\t\t\t" # e_str_j_1 += "e_" + str(i) + "_" + "0" + ": " + str(int(e_variables[i][0].varValue)) + "\t\t\t" # e_str_j_2 += "e_" + str(i) + "_" + "1" + ": " + str(int(e_variables[i][1].varValue)) + "\t\t\t" # n_str_j_1 += "n_" + str(i) + "_" + "0" + ": " + str(int(n_variables[i][0].varValue)) + "\t\t\t" # n_str_j_2 += "n_" + str(i) + "_" + "1" + ": " + str(int(n_variables[i][1].varValue)) + "\t\t\t" # p_str_j_1 += "p_" + str(i) + "_" + "0" + ": " + str(int(p_variables[i][0].varValue)) + "\t\t\t" # p_str_j_2 += "p_" + str(i) + "_" + "1" + ": " + str(int(p_variables[i][1].varValue)) + "\t\t\t" # v_str_j_1 += "v_" + str(i) + "_" + "0" + ": " + str(int(v_variables[i][0].varValue)) + "\t\t\t" # v_str_j_2 += "v_" + str(i) + "_" + "1" + ": " + str(int(v_variables[i][1].varValue)) + "\t\t\t" # for i in range(len(trace) + 1): # t_str_j_1 += "t_" + str(i) + "_" + "0" + ": " + str(int(t_variables[i][0].varValue)) + "\t\t\t" # t_str_j_2 += "t_" + str(i) + "_" + "1" + ": " + str(int(t_variables[i][1].varValue)) + "\t\t\t" # # logging.debug(trace_str) # logging.debug(t_str_j_1) # logging.debug(t_str_j_2) # logging.debug(x_str_j_1) # logging.debug(x_str_j_2 + "\n") # logging.debug(s_str_j_1) # logging.debug(s_str_j_2 + "\n") # logging.debug(e_str_j_1) # logging.debug(e_str_j_2 + "\n") # logging.debug(n_str_j_1) # logging.debug(n_str_j_2 + "\n") # logging.debug(p_str_j_1) # logging.debug(p_str_j_2 + "\n") # logging.debug(v_str_j_1) # logging.debug(v_str_j_2 + "\n") alignments_to_calculate: List[Tuple[ProcessTree, Trace]] = [] sub_trace = Trace() current_subtree_idx = 0 for i in range(len(trace)): for j in range(2): if t_variables[i][j].varValue: if i == 0: # first tau can be only assigned to first subtree assert j == 0 alignments_to_calculate.append((pt.children[j], Trace())) current_subtree_idx = 1 else: alignments_to_calculate.append( (pt.children[current_subtree_idx], sub_trace)) alignments_to_calculate.append((pt.children[j], Trace())) sub_trace = Trace() for j in range(2): if x_variables[i][j].varValue: if j == current_subtree_idx: sub_trace.append(trace[i]) else: alignments_to_calculate.append( (pt.children[current_subtree_idx], sub_trace)) sub_trace = Trace() sub_trace.append(trace[i]) current_subtree_idx = j if len(sub_trace) > 0: alignments_to_calculate.append( (pt.children[current_subtree_idx], sub_trace)) if t_variables[len(trace)][0].varValue: alignments_to_calculate.append((pt.children[0], Trace())) res = [] for subtree, sub_trace in alignments_to_calculate: res.extend( approximate_alignment(subtree, pt_a_set, pt_sa_set, pt_ea_set, pt_tau_flag, sub_trace, tl, th)) return res
from pulp import LpVariable, LpProblem, LpMaximize, LpStatus, value prob = LpProblem("dual_problem.py", LpMaximize) x1 = LpVariable("Prod_1", 0, cat='Integer') x2 = LpVariable("Prod_2", 0, cat='Integer') profit_x1 = 5 profit_x2 = 6 products = [x1, x2] resources = [0, 1, 2] capabilities = [14, 9, 56] costs = [[1, 1, 7], [2, 1, 4]] # Objective Function prob += profit_x1 * x1 + profit_x2 * x2 # Constrains prob += costs[0][0] * x1 + costs[1][0] * x2 <= capabilities[0] prob += costs[0][1] * x1 + costs[1][1] * x2 <= capabilities[1] prob += costs[0][2] * x1 + costs[1][2] * x2 <= capabilities[2] prob += capabilities[0] + capabilities[1] + capabilities[2] <= sum( capabilities) prob += costs[0][0] * capabilities[0] + costs[0][1] * capabilities[1] + costs[ 0][2] * capabilities[2] >= profit_x1 prob += costs[1][0] * capabilities[0] + costs[1][1] * capabilities[1] + costs[ 1][2] * capabilities[2] >= profit_x2 prob.writeLP('dual_problem.py') print(prob) print('Solution')