for var in chain(chemicals.values(), reactions.values()): constraints.append(var >= 0) for out_chemical, (quantity, inputs) in recipes.items(): constraints.append(chemicals[out_chemical] == quantity * reactions[out_chemical]) for chemical, quantity in inputs.items(): quantities_required[chemical].append(reactions[out_chemical] * quantity) for chemical, required in quantities_required.items(): if not required: continue constraints.append(chemicals[chemical] >= pulp.lpSum(required)) # part 1 prob = pulp.LpProblem("day_14.1", pulp.LpMinimize) for c in constraints: prob += c prob += chemicals["ORE"] # Minimize this prob += chemicals["FUEL"] >= 1 prob.solve() print(("Status:", pulp.LpStatus[prob.status])) print('Part 1:', pulp.value(chemicals["ORE"])) # part 2 prob = pulp.LpProblem("day_14.2", pulp.LpMaximize) for c in constraints: prob += c prob += chemicals["FUEL"] # Maximize this prob += chemicals["ORE"] == 1_000_000_000_000
def __calcW(self, goal=1, eps=0.00): oidx = [i for i in range(self.M)] Nsols = len(self.solutionsList) # Create a gurobi model prob = lp.LpProblem("max_mean", lp.LpMaximize) # prob = mip.Model(sense=mip.MAXIMIZE, solver_name=mip.GRB) # Creation of linear integer variables w = list( lp.LpVariable.dicts('w', oidx, lowBound=0, cat='Continuous').values()) # w = list(prob.add_var(name='w', var_type=mip.CONTINUOUS, lb=0) for i in range(len(Ingredients))) uR = list(lp.LpVariable.dicts('uR', oidx, cat='Continuous').values()) # uR = list() kp = list( lp.LpVariable.dicts('kp', list(range(Nsols)), cat='Continuous').values()) # kp = list() nu = list( lp.LpVariable.dicts('nu', oidx, lowBound=0, cat='Continuous').values()) # nu = list() test = False if test: kpB = list( lp.LpVariable.dicts('kpB', list(range(Nsols)), lowBound=0, upBound=1, cat='Continuous').values()) nuB = list( lp.LpVariable.dicts('nuB', oidx, lowBound=0, upBound=1, cat='Continuous').values()) else: kpB = list( lp.LpVariable.dicts('kpB', list(range(Nsols)), cat='Binary').values()) nuB = list(lp.LpVariable.dicts('nuB', oidx, cat='Binary').values()) v = lp.LpVariable('v', cat='Continuous') mu = lp.LpVariable('mu', cat='Continuous') # Inherent constraints of this problem for value, sols in enumerate(self.solutionsList): expr = lp.lpDot(self.__normw(sols.w), uR) cons = self.__normf(sols.objs) @ self.__normw(sols.w) prob += expr >= cons * (1 - eps) for i in oidx: expr = uR[i] - lp.lpSum([ kp[conN] * self.__normf(sols.objs)[i] for conN, sols in enumerate(self.solutionsList) ]) - nu[i] + mu prob += expr == 0 bigC = max(self.__normf(self.__globalU)) for conN, sols in enumerate(self.solutionsList): # d, dvec = self.__calcD(sols) expr = v - lp.lpDot(w, self.__normf(sols.objs)) prob += -expr >= 0 #mantem prob += -expr <= kpB[conN] * bigC #mantem prob += kp[conN] >= 0 #mantem prob += kp[conN] <= (1 - kpB[conN]) #mantem for i in oidx: prob += uR[i] >= self.__normf(self.__globalL)[i] for i in oidx: prob += w[i] >= 0 #mantem prob += w[i] <= nuB[i] #mantem prob += nu[i] >= 0 #mantem prob += nu[i] <= (1 - nuB[i]) * 2 * bigC #mantem prob += lp.lpSum([w[i] for i in oidx]) == 1 prob += lp.lpSum([kp[i] for i in range(Nsols)]) == 1 prob += mu # desigualdades válidas prob += mu <= v try: rnd = np.array( sorted([0] + [np.random.rand() for i in range(self.M - 1)] + [1])) w_ini = np.array([rnd[i + 1] - rnd[i] for i in range(self.__M)]) w_ini = w_ini / w_ini.sum() for wi, wii in zip(w, w_ini): wi.start = wii grbs = lp.GUROBI(epgap=self.__mip_gap, SolutionLimit=1, msg=False, OutputFlag=False, Threads=1) prob.solve(grbs) if self.__goal != float('inf'): grbs = lp.GUROBI(timeLimit=self.__time_limit, epgap=self.__mip_gap, SolutionLimit=MAXINT, msg=False, BestObjStop=self.__goal, OutputFlag=False, Threads=1) else: grbs = lp.GUROBI(timeLimit=self.__time_limit, epgap=self.__mip_gap, SolutionLimit=MAXINT, msg=False, OutputFlag=False, Threads=1) prob.solve(grbs) except: cbcs = lp.COIN_CMD(maxSeconds=self.__time_limit, fracGap=self.__mip_gap, threads=1) prob.solve(cbcs, use_mps=False) feasible = False if prob.status in [-1, -2] else True if feasible: w_ = np.array( [lp.value(w[i]) if lp.value(w[i]) >= 0 else 0 for i in oidx]) w_ = w_ / w_.sum() if self.__norm: w_ = w_ / (self.__globalU - self.__globalL) fobj = lp.value(prob.objective) self.__w = np.array(w_) self.__importance = fobj else: raise ('Non-feasible solution')
z_comb[i]=tempL Y=40 print('Finish Data Preprocess!') print(modelList) #####前面主要是数据处理部分######## #以上主要是将订单的信息按照型号与交付时间重新划分了新的型号,三个月内的相同型号的点订单放在一起生产。 #以上同时做了一个维,用于计算每个型号在产线的速度(每天都不一样,指数增长) #####后面是模型,用到了mixed integer linear print('LP process begins.') prob=pulp.LpProblem("The APS Problem",pulp.LpMinimize) x={} h={} k={} wt={} f={} ft={} wn={} z={} modeln=len(modelList) for i in modelList: #a variable which is one if order j of the model i is completed in time t #订单j (型号i) 在t时间完成生产(下线时间)-类型:binary x[i]=pulp.LpVariable.dicts('x',x_comb[i],0,1,pulp.LpInteger) # a variable which is 1 in period t if all orders of model i
def solve(studentInfos, groupInfos, goalGroups): # Set up groups groups = [] gidToGroupInfo = {} nextGID = 1 for group in groupInfos: groupObj = Group(nextGID, group) if groupObj.size != None and groupObj.size == 0: # Skip groups with no room continue groups.append(groupObj) gidToGroupInfo[groupObj.id] = group nextGID += 1 # Set up students students = [] sidToStudentInfo = {} nextSID = 1 for student in studentInfos: studentObj = Student(nextSID, student, groups) students.append(studentObj) sidToStudentInfo[studentObj.id] = student nextSID += 1 # Set up data box dataBox = DataBox(students, groups) # Run for each set of goals until 'Optimal' is found, or return None for i in range(len(goalGroups)): goals = goalGroups[i] problem = pulp.LpProblem("Group Membership Problem", pulp.LpMaximize) # Add student constraints failedAddingConstraints = False for student in students: constraints = student.genConstraints() if constraints == None: failedAddingConstraints = True break for constraint in constraints: problem += constraint # Add group constraints for group in groups: constraints = group.genConstraints() if constraints == None: failedAddingConstraints = True break for constraint in constraints: problem += constraint # Add goal constraints for goal in goals: constraints = goal.genConstraints(dataBox) if constraints == None: failedAddingConstraints = True break for constraint in constraints: problem += constraint if failedAddingConstraints: print "> Goal group " + str( i ) + " failed because constraints couldn't be generated. Trying next goal group..." continue # Objective function # TODO: add objective function # Attempt to solve problem.solve() solved = pulp.LpStatus[problem.status] == 'Optimal' if solved: print "> Successful with goal group " + str(i) output = [None for i in range(len(groups))] #output = [{"students": [students], "group": groupinfo}, ...] for variable in problem.variables(): if variable.name == '__dummy': continue if variable.varValue == 0: continue ret = Utils.decodeVarName(variable.name) if ret == None: continue (sid, gid) = ret student = sidToStudentInfo[sid] group = gidToGroupInfo[gid] index = gid - 1 if output[index] == None: output[index] = {} output[index]['students'] = [] output[index]['info'] = group output[index]['students'].append(student) return output else: print "> Goal group " + str( i) + " was too strict. Trying next goal group..." print "> All goal groups were too strict. No groups could be created" return None
import pulp x1=pulp.LpVariable("x1",lowBound=0) x2=pulp.LpVariable("x2",lowBound=0) x3=pulp.LpVariable("x3",upBound=0) optimum=pulp.LpProblem("max",pulp.LpMaximize) optimum+=2*x2-x3+3, "objective function" optimum+=x1+x2+x3<=3 optimum+=x1+x2+x3>=3 optimum+=x1-x2>=1 optimum+=x2-x3<=1 optimum+=x1+x2>=3 optimum.solve() print("decision variable values") for variable in optimum.variables(): print(variable.name,"=",variable.varValue) print("\nmax:") pulp.value(optimum.objective)
def optimizeTrajectory(N, T, T_end, V, P, W, M, m, TSFC, minApproachDist, x_ini, x_fin, x_lim, u_lim, objects, r): # -------------------- # Calculated Variables # -------------------- del_t = T_end/T numObjects = objects.shape[0] # ------------------ # Decision variables # ------------------ # Thrust u = pulp.LpVariable.dicts( "input", ((i, p, n) for i in range(T) for p in range(V) for n in range(N)), cat='Continuous') # Thrust Magnitude v = pulp.LpVariable.dicts( "inputMag", ((i, p, n) for i in range(T) for p in range(V) for n in range(N)), lowBound=0, cat='Continuous') # State x = pulp.LpVariable.dicts( "state", ((i, p, k) for i in range(T) for p in range(V) for k in range(2*N)), cat='Continuous') # Object collision a = pulp.LpVariable.dicts( "objCol", ((i, p, l, k) for i in range(T) for p in range(V) for l in range(numObjects) for k in range(2*N)), cat='Binary') # Satellite Collision Avoidance b = pulp.LpVariable.dicts( "satelliteCollisionAvoidance", ((i, p, q, k) for i in range(T) for p in range(V) for q in range(V) for k in range(2*N)), cat='Binary') # Plume Impingement c_plus = pulp.LpVariable.dicts( "plumeImpingementPositive", ((i, p, q, n, k) for i in range(T) for p in range(V) for q in range(V) for n in range(N) for k in range(2*N)), cat='Binary') c_minus = pulp.LpVariable.dicts( "plumeImpingementNegative", ((i, p, q, n, k) for i in range(T) for p in range(V) for q in range(V) for n in range(N) for k in range(2*N)), cat='Binary') # ------------------ # Optimization Model # ------------------ # Instantiate Model model = pulp.LpProblem("Satellite Fuel Minimization Problem", pulp.LpMinimize) # Objective Function model += pulp.lpSum(v[i, p, n] for i in range(T) for p in range(V) for n in range(N)), "Fuel Minimization" # ----------- # Constraints # ----------- # Basic Constraints # ----------------- # Constrain thrust magnitude to abs(u[i, p, n]) for i in range(T): for p in range(V): for n in range(N): model += u[i, p, n] <= v[i, p, n] model += -u[i, p, n] <= v[i, p, n] # State and Input vector start and end values for p in range(V): for k in range(2*N): model += x[0, p, k] == x_ini[p, k] model += x[T-1, p, k] == x_fin[p, k] # Model Dynamics for constraint in freeSpaceDynamics(x, u, T, V, N, m, del_t): model += constraint # State and Input vector limits for i in range(T): for p in range(V): for n in range(N): model += u[i, p, n] <= u_lim[p, n] model += u[i, p, n] >= -u_lim[p, n] for k in range(2*N): # Necessary? model += x[i, p, k] <= x_lim[p, k] model += x[i, p, k] >= -x_lim[p, k] # Obstacle Avoidance # ------------------ if objects.shape[1] > 0: for i in range(T): for p in range(V): for l in range(numObjects): model += pulp.lpSum(a[i, p, l, n] for n in range(2*N)) <= 2*N-1 for n in range(N): model += x[i, p, n] >= objects[l, N+n] + minApproachDist - M*a[i, p, l, N+n] model += x[i, p, n] <= objects[l, n] - minApproachDist + M*a[i, p, l, n] # Collision Avoidance # ------------------- if V > 1: # If more than one vehicle for i in range(T): for p in range(V): for q in range(V): if q > p: model += pulp.lpSum(b[i, p, q, k] for k in range(2*N)) <= 2*N-1 for n in range(N): model += x[i, p, n] - x[i, q, n] >= r[n] - M*b[i, p, q, n] model += x[i, q, n] - x[i, p, n] >= r[n] - M*b[i, p, q, n+N] # Plume Impingement # ----------------- # Positive thrust if V > 1: # If more than one vehicle for i in range(T): for p in range(V): for q in range(V): if q != p: for n in range(N): model += pulp.lpSum(c_plus[i, p, q, n, k] for k in range(2*N)) <= 2*N model += -u[i, p, n] >= - M*c_plus[i, p, q, n, 0] model += x[i, p, n] - x[i, q, n] >= P - M*c_plus[i, p, q, n, n] model += x[i, q, n] - x[i, p, n] >= - M*c_plus[i, p, q, n, n+N] for m in range(N): if m != n: x[i, p, m] - x[i, q, m] >= W - M*c_plus[i, p, q, n, m] x[i, q, m] - x[i, p, m] >= W - M*c_plus[i, p, q, n, m+N] # Negative thrust for i in range(T): for p in range(V): for q in range(V): if q != p: for n in range(N): model += pulp.lpSum(c_minus[i, p, q, n, k] for k in range(2*N)) <= 2*N model += u[i, p, n] >= - M*c_minus[i, p, q, n, 0] model += x[i, p, n] - x[i, q, n] >= - M*c_minus[i, p, q, n, n] model += x[i, q, n] - x[i, p, n] >= P - M*c_minus[i, p, q, n, n+N] for m in range(N): if m != n: x[i, p, m] - x[i, q, n] >= W - M*c_minus[i, p, q, n, m] x[i, q, m] - x[i, p, m] >= W - M*c_minus[i, p, q, n, m+N] # Plume Avoidance for Vehicles # ---------------------------- # Plume Avoidance for Obstacles # ----------------------------- # Final Configuration Selection # ----------------------------- # Solve model and return results in dictionary model.solve(pulp.CPLEX()) # Create Pandas dataframe for results and return return {'model':model, 'x':x, 'u':u}
def tensors(self): """Constructs high-level DAG and creates the tensors. Returns: An collections.OrderedDict mapping a tensor's name to the tensor. """ # TODO: check for name conflicts tensor_map = collections.OrderedDict() for stmt in self.input_stmts: tensor = soda.tensor.Tensor(stmt, self.tile_size) tensor_map[stmt.name] = tensor def name_in_iter(name, iteration): if name in self.input_names: if iteration > 0: return name + '_iter%d' % iteration return name if name in self.output_names: if iteration < self.iterate - 1: return (self.input_names[self.output_names.index(name)] + '_iter%d' % (iteration + 1)) return name if name in self.local_names: if iteration > 0: return name + '_iter%d' % iteration return name if name in self.param_names: return name raise util.InternalError('unknown name: %s' % name) for iteration in range(self.iterate): _logger.debug('iterate %s', iteration) _logger.debug('map: %s', self.symbol_table) def mutate_name_callback(obj, mutated): if isinstance(obj, ir.Ref): obj.haoda_type = self.symbol_table[obj.name] # pylint: disable=cell-var-from-loop obj.name = name_in_iter(obj.name, iteration) return obj tensors = [] for stmt in itertools.chain(self.local_stmts, self.output_stmts): tensor = soda.tensor.Tensor(stmt.visit(mutate_name_callback), self.tile_size) tensor_map[tensor.name] = tensor tensors.append(tensor) for tensor in tensors: _logger.debug('%s', tensor) for tensor in tensors: tensor.propagate_type() loads = visitor.get_load_dict(tensor) for parent_name, ld_refs in loads.items(): ld_refs = sorted(ld_refs, key=lambda ref: soda.util.serialize( ref.idx, self.tile_size)) parent_tensor = tensor_map[parent_name] parent_tensor.children[tensor.name] = tensor tensor.parents[parent_name] = parent_tensor tensor.ld_refs[parent_name] = ld_refs # solve ILP for optimal reuse buffer lp_problem = pulp.LpProblem("optimal_reuse_buffer", pulp.LpMinimize) lp_vars = {self.input_names[0]: 0} # set 1 and only 1 reference point lp_helper_vars = {} # type: Dict[str, pulp.LpVariable] objectives = [] constraints = [] for tensor in tensor_map.values(): lp_var = pulp.LpVariable('produced_offset_' + tensor.name, cat='Integer') lp_helper_var = pulp.LpVariable('consumed_offset_' + tensor.name, cat='Integer') lp_vars.setdefault(tensor.name, lp_var) lp_helper_vars[tensor.name] = lp_helper_var # tensor need to be kept for this long objectives.append(lp_helper_var - lp_vars[tensor.name]) # tensor cannot be consumed until it is produced constraints.append(lp_helper_var >= lp_vars[tensor.name]) lp_problem += sum(objectives) lp_problem.extend(constraints) for st_tensor in tensor_map.values(): for ld_tensor_name, offsets in st_tensor.ld_offsets.items(): oldest_access = min(offsets) newest_access = max(offsets) _logger.debug('%s @ %s accesses %s @ [%s, %s]', st_tensor.name, st_tensor.st_offset, ld_tensor_name, oldest_access, newest_access) # newest ld_tensor access must have been produced # when st_tensor is produced lp_problem += lp_vars[ld_tensor_name] <= lp_vars[ st_tensor.name] + (st_tensor.st_offset - newest_access) # oldest ld_tensor access must have been not consumed # when st_tensor is produced lp_problem += lp_helper_vars[ld_tensor_name] >= lp_vars[ st_tensor.name] + (st_tensor.st_offset - oldest_access) lp_status = lp_problem.solve() lp_status_str = pulp.LpStatus[lp_status] total_distance = int(pulp.value(lp_problem.objective)) _logger.debug('ILP status: %s %s', lp_status_str, total_distance) _logger.info('total reuse distance: %d', total_distance) if lp_status != pulp.LpStatusOptimal: _logger.error('ILP error: %s\n%s', lp_status_str, lp_problem) raise util.InternalError('unexpected ILP status: %s' % lp_status_str) # some inputs may need to be delayed relative to others base = min(int(pulp.value(lp_vars[x])) for x in self.input_names) # set produce offsets for tensor in tensor_map.values(): produce_offset = int(pulp.value(lp_vars[tensor.name])) - base consume_offset = int(pulp.value( lp_helper_vars[tensor.name])) - base tensor.produce_offset = produce_offset tensor.consume_offset = consume_offset tensor.max_access = 0 # pixels before current produce _logger.debug('%s should be produced @ %d and kept until %d', tensor.name, produce_offset, consume_offset) # calculate overall acceses for ld_tensor in tensor_map.values(): for st_tensor in ld_tensor.children.values(): oldest_access = st_tensor.st_offset - min( st_tensor.ld_offsets[ld_tensor.name] ) + st_tensor.produce_offset - ld_tensor.produce_offset newest_access = st_tensor.st_offset - max( st_tensor.ld_offsets[ld_tensor.name] ) + st_tensor.produce_offset - ld_tensor.produce_offset _logger.debug( ' producing %s @ %s accesses [%s, %s] pixels before %s ' 'produced @ %s', st_tensor.name, st_tensor.produce_offset, newest_access, oldest_access, ld_tensor.name, ld_tensor.produce_offset) ld_tensor.max_access = max(ld_tensor.max_access, oldest_access) for tensor in tensor_map.values(): _logger.debug('%s should be kept for %s pixels', tensor.name, tensor.max_access) # high-level DAG construction finished for tensor in tensor_map.values(): if tensor.name in self.input_names: _logger.debug('<input tensor>: %s', tensor) elif tensor.name in self.output_names: _logger.debug('<output tensor>: %s', tensor) else: _logger.debug('<local tensor>: %s', tensor) return tensor_map
/ 3600 #converting kJ to kWh ECF booster in kWh/kmol # Converting the transportation constants to m^3 MW_H2 = var['value']['MW_H2'] #kg/kmol H2 density_H2 = var['value']['density_H2'] #kg/m^3 Imax = Imax * MW_H2 / density_H2 # m^3 Imin = Imin * MW_H2 / density_H2 # m^3 Fmax_booster = Fmax_booster * MW_H2 / density_H2 # m^3 Fmax_prestorage = Fmax_prestorage * MW_H2 / density_H2 # m^3 ECF_booster = ECF_booster / MW_H2 * density_H2 #kWh/m^3 ECF_prestorage = ECF_prestorage / MW_H2 * density_H2 #kWh/m^3 # RNG + HENG model LP_eps = pulp.LpProblem('LP_eps', pulp.LpMaximize) LP_cost = pulp.LpProblem('LP_cost', pulp.LpMinimize) # RNG Variables RNG_max = pulp.LpVariable('RNG_max', lowBound=0, cat='Continuous') N_electrolyzer_1 = pulp.LpVariable('N_electrolyzer_1', lowBound=0, cat='Integer') alpha_1 = pulp.LpVariable.dicts('alpha_1', [str(i) for i in range(1, N_max)], cat='Binary') E_1 = pulp.LpVariable.dicts('E_1', [str(i) for i in input_df.index], lowBound=0,
def IP_solution(self): """ This method implements the IP solution. Args: - self: Sudoku instance, to be solved using IP. Returns: - flag: boolean, whether the Sudoku is solvable. If True, the completed Sudoku is available through the attribute "_solution" and the completion time through "_duration". """ # List of available digits Digits = ["1", "2", "3", "4", "5", "6", "7", "8", "9"] Values = Digits Rows = Digits Columns = Digits # Creating the block list Blocks = [] for i in range(3): for j in range(3): Blocks += [[(Rows[3 * i + k], Columns[3 * j + l]) for k in range(3) for l in range(3)]] # We need to create the IP problem prob = pulp.LpProblem("Sudoku solver", pulp.LpMinimize) # Then we create the problem variables choices = pulp.LpVariable.dicts("Choice", (Rows, Columns, Values), 0, 1, pulp.LpInteger) # We define the objective function which is 0 here prob += 0, "Objective Function" # Defining the constraint: only one value can be put in a cell for r in Rows: for c in Columns: prob += pulp.lpSum([choices[r][c][v] for v in Values]) == 1, "" for v in Values: # Each value must occur exactly once in each row for r in Rows: prob += pulp.lpSum([choices[r][c][v] for c in Columns]) == 1, "" # Each value must occur exactly once in each column for c in Columns: prob += pulp.lpSum([choices[r][c][v] for r in Rows]) == 1, "" # Each value must occur exactly once in each block for b in Blocks: prob += pulp.lpSum([choices[r][c][v] for (r, c) in b]) == 1, "" # We need to add the starting numbers as constraints grid = self.grid for r in range(len(grid)): for c in range(len(grid[0])): value = grid[r][c] if value != 0: prob += choices[str(int(r + 1))][str(int(c + 1))][str( int(value))] == 1, "" solve_value = prob.solve() # flag is True is solve_value evaluates to 1 i.e. the Sudoku can be # solved flag = solve_value == 1 if flag: solution_grid = np.zeros((9, 9)) for r in Rows: for c in Columns: for v in Values: if choices[r][c][v].value() == 1.0: solution_grid[int(r) - 1][int(c) - 1] = v self._solution = solution_grid return flag
# append distance to result list _distance_result[i][j] = _google_maps_api_result[0]['legs'][0][ 'distance']['value'] return _distance_result distance = _distance_calculator(df) plot_result = _plot_on_gmaps(df) plot_result # solve with pulp for vehicle_count in range(1, vehicle_count + 1): # definition of LpProblem instance problem = pulp.LpProblem("CVRP", pulp.LpMinimize) # definition of variables which are 0/1 x = [[[ pulp.LpVariable("x%s_%s,%s" % (i, j, k), cat="Binary") if i != j else None for k in range(vehicle_count) ] for j in range(customer_count)] for i in range(customer_count)] # add objective function problem += pulp.lpSum(distance[i][j] * x[i][j][k] if i != j else 0 for k in range(vehicle_count) for j in range(customer_count) for i in range(customer_count)) # constraints
def job_selector_ilp(self, jobs): """ Job scheduling by optimization of resource usage by solving ILP using pulp """ import pulp from pulp import lpSum # assert self.resources["_cores"] > 0 scheduled_jobs = { job: pulp.LpVariable( "job_{}".format(idx), lowBound=0, upBound=1, cat=pulp.LpInteger, ) for idx, job in enumerate(jobs) } temp_files = { temp_file for job in jobs for temp_file in self.dag.temp_input(job) } temp_job_improvement = { temp_file: pulp.LpVariable("temp_file_{}".format(idx), lowBound=0, upBound=1, cat="Continuous") for idx, temp_file in enumerate(temp_files) } temp_file_deletable = { temp_file: pulp.LpVariable( "deletable_{}".format(idx), lowBound=0, upBound=1, cat=pulp.LpInteger, ) for idx, temp_file in enumerate(temp_files) } prob = pulp.LpProblem("JobScheduler", pulp.LpMaximize) total_temp_size = max( sum([temp_file.size for temp_file in temp_files]), 1) total_core_requirement = sum( [max(job.resources.get("_cores", 1), 1) for job in jobs]) # Objective function # Job priority > Core load # Core load > temp file removal # Instant removal > temp size prob += (2 * total_core_requirement * 2 * total_temp_size * lpSum( [job.priority * scheduled_jobs[job] for job in jobs]) + 2 * total_temp_size * lpSum([ max(job.resources.get("_cores", 1), 1) * scheduled_jobs[job] for job in jobs ]) + total_temp_size * lpSum([ temp_file_deletable[temp_file] * temp_file.size for temp_file in temp_files ]) + lpSum([ temp_job_improvement[temp_file] * temp_file.size for temp_file in temp_files ])) # Constraints: for name in self.workflow.global_resources: prob += (lpSum([ scheduled_jobs[job] * job.resources.get(name, 0) for job in jobs ]) <= self.resources[name]) # Choose jobs that lead to "fastest" (minimum steps) removal of existing temp file remaining_jobs = self.remaining_jobs for temp_file in temp_files: prob += temp_job_improvement[temp_file] <= lpSum([ scheduled_jobs[job] * self.required_by_job(temp_file, job) for job in jobs ]) / lpSum([ self.required_by_job(temp_file, job) for job in remaining_jobs ]) prob += temp_file_deletable[temp_file] <= temp_job_improvement[ temp_file] solver = (pulp.get_solver(self.scheduler_ilp_solver) if self.scheduler_ilp_solver else pulp.apis.LpSolverDefault) solver.msg = False # disable extensive logging try: prob.solve(solver) except pulp.apis.core.PulpSolverError as e: raise WorkflowError( "Failed to solve the job scheduling problem with pulp. " "Please report a bug and use --scheduler greedy as a workaround:\n{}" .format(e)) selected_jobs = set(job for job, variable in scheduled_jobs.items() if variable.value() == 1.0) for name in self.workflow.global_resources: self.resources[name] -= sum( [job.resources.get(name, 0) for job in selected_jobs]) return selected_jobs
def optimize(self): self.lineups_created = 0 self.filter_players() prob = pulp.LpProblem('Opti', pulp.LpMaximize) try: #adds decision variables self.p_vars = { player_id: pulp.LpVariable(str(player_id), cat='Binary') for player_id in self.players['player_id'] } self.t_vars = [ pulp.LpVariable(str(team), cat='Binary') for team in self.teams ] #to be used for team constraints only, not objective #adds objective function prob += (pulp.lpSum(self.players.loc[p_id, self.proj_type] * self.p_vars[p_id] for p_id in self.players['player_id'])) #add player number constraints prob += (pulp.lpSum(self.p_vars[p_id] for p_id in self.players['player_id']) == 9) #add position constraints prob += (pulp.lpSum( self.positions.loc[p_id, 'C'] * self.p_vars[p_id] for p_id in self.players['player_id']) >= 2) prob += (pulp.lpSum( self.positions.loc[p_id, 'C'] * self.p_vars[p_id] for p_id in self.players['player_id']) <= 4) prob += (pulp.lpSum( self.positions.loc[p_id, 'W'] * self.p_vars[p_id] for p_id in self.players['player_id']) >= 2) prob += (pulp.lpSum( self.positions.loc[p_id, 'W'] * self.p_vars[p_id] for p_id in self.players['player_id']) <= 4) prob += (pulp.lpSum( self.positions.loc[p_id, 'D'] * self.p_vars[p_id] for p_id in self.players['player_id']) >= 2) prob += (pulp.lpSum( self.positions.loc[p_id, 'D'] * self.p_vars[p_id] for p_id in self.players['player_id']) <= 4) prob += (pulp.lpSum(self.positions.loc[p_id, 'G'] * self.p_vars[p_id] for p_id in self.players['player_id']) == 1) for team in self.teams: #adds number of players per team constraint prob += (pulp.lpSum( self.teams.loc[p_id, team] * self.p_vars[p_id] for p_id in self.players['player_id']) <= 4) #contrains team variable to be 0 when no players from a team are added, 1 otherwise prob += (pulp.lpSum( self.teams.loc[p_id, team] * self.p_vars[p_id] for p_id in self.players['player_id']) >= self.t_vars[list( self.teams).index(team)]) #adds number of total teams constraint prob += (pulp.lpSum(team for team in self.t_vars) >= 3) #adds constraint where no skaters can face goalie for goalie in self.opp_skaters: prob += (6 * self.p_vars[goalie] + pulp.lpSum( self.opp_skaters.loc[p_id, goalie] * self.p_vars[p_id] for p_id in self.players['player_id']) <= 6) #adds locked players constraints for player in self.lock_players: prob += (self.p_vars[player] == 1) #add salary constraint prob += (pulp.lpSum( self.players.loc[p_id, 'salary'] * self.p_vars[p_id] for p_id in self.players['player_id']) <= 55000) #creates list with optimal solutions self.lineups = self.load_lineups(prob) #sets dataframe with percentage of lineups a player is in self.percentages = self.set_percentages() except: self.lineups = {} self.percentages = None
def construct_ILP( self, T: int, q_max: int, inn: Dict[int, Dict], out: Dict[int, Dict], p_inn, p_out, current_inventory: int, ): t0 = time.time() # Generate the pulp problem. model = pulp.LpProblem("Business_Plan_Solver", pulp.LpMaximize) # Generate the integer 0/1 decision variables. There are two kinds: inn_vars[t][k] and out_vars[t][k] # inn_vars[t][k] == 1 iff in the business plan the agent tries to buy k inputs at time t inn_vars = pulp.LpVariable.dicts( "inn", ((t, k) for t, k in it.product( range(self.current_time, self.current_time + T), range(0, q_max))), lowBound=0, upBound=1, cat="Integer", ) # out_vars[t][k] == 1 iff in the business plan the agent tries to sell k inputs at time t out_vars = pulp.LpVariable.dicts( "out", ((t, k) for t, k in it.product( range(self.current_time, self.current_time + T), range(0, q_max))), lowBound=0, upBound=1, cat="Integer", ) # print(f'it took {time.time() - t0 : .4f} to generate dec. vars') # Generate the objective function - the total profit of the plan. Profit = revenue - cost # Here, revenue is the money received from sales of outputs, and cost is the money used to buy inputs. model += pulp.lpSum([ out_vars[t, k] * out[t][k] * p_out[str(t)] - inn_vars[t, k] * inn[t][k] * p_inn[str(t)] for t, k in it.product( range(self.current_time, self.current_time + T), range(0, q_max)) ]) # print(f'it took {time.time() - t0 : .4f} to generate objective function') # Genrate the constraints. Only one quantity can be planned for at each time step for buying or selling. for t in range(self.current_time, self.current_time + T): model += sum([out_vars[t, k] for k in range(0, q_max)]) <= 1 model += sum([inn_vars[t, k] for k in range(0, q_max)]) <= 1 # print(f'it took {time.time() - t0 : .4f} to generate constraints ') # Document here: optimistic == True means no bluffing, otherwise there is bluffing going on optimistic = True if optimistic: # ToDo: add redundant constraint that models: the number of inputs == number of outputs # Constraints that ensure there are enough outputs to sell at each time step. right_hand_size = current_inventory for t in range(self.current_time, self.current_time + T): model += (sum([out_vars[t, k] * k for k in range(0, q_max)]) <= right_hand_size) right_hand_size += sum([ inn_vars[t, k] * k - out_vars[t, k] * k for k in range(0, q_max) ]) else: # Constraints that ensure there are enough outputs, in expectation, to sell at each time step. right_hand_size = current_inventory for t in range(self.current_time, self.current_time + T): model += (sum( [out_vars[t, k] * out[t][k] for k in range(0, q_max)]) <= right_hand_size) right_hand_size += sum([ inn_vars[t, k] * inn[t][k] - out_vars[t, k] * out[t][k] for k in range(0, q_max) ]) # We assume that the planning starts with no inventory and thus, the agent cannot sell anything at time 0. # for k in range(current_inventory+1, q_max): # model += out_vars[0, k] == 0 time_to_generate_ILP = time.time() - t0 # print(f'it took {time_to_generate_ILP : .4f} to generate the ILP') # return inn_vars, model, optimistic, out_vars, t0, time_to_generate_ILP # solve ILP t0_solve = time.time() model.solve() solve_time = time.time() - t0_solve # print(f'it took {solve_time : .4f} sec to solve, result = {pulp.LpStatus[model.status]}') total_time = time.time() - t0 # print(f"MODEL OBJECTIVE: {pulp.value(model.objective)}") # #print(f'it took {total_time : .4f} sec in total, and has opt profit of {pulp.value(model.objective) : .4f}') t0 = time.time() buy_plan = { t: sum([int(k * inn_vars[t, k].varValue) for k in range(0, q_max)]) for t in range(self.current_time, self.current_time + T) } sell_plan = { t: sum([int(k * out_vars[t, k].varValue) for k in range(0, q_max)]) for t in range(self.current_time, self.current_time + T) } # print(f'it took {time.time() - t0 : .4f} sec to produce the plan') return ( buy_plan, sell_plan, solve_time, total_time, inn_vars, model, optimistic, out_vars, t0, time_to_generate_ILP, )
def solve_gc_IP(G, k, solver, threads, plot, pos): """ k-彩色問題を通常の定式化で解く 入力 G: グラフ k(int): 色数 solver: "cbc" or "cplex" or "gurobi" threads: gurobiの場合指定 plot: trueの場合plotする 出力 # ><><><><><><><><><><><><><><><><><><><><>< # ><><><><><><><><><><><><><><><><><><><><>< # ><><><><><><><><><><><><><><><><><><><><>< # ><><><><><><><><><><><><><><><><><><><><>< """ colors = list(range(1, k+1)) nodes = G.nodes edges = G.edges problem = pulp.LpProblem(f'{k}-Coloring Problem', pulp.LpMinimize) problem += 0 var = { node: pulp.LpVariable.dicts(str(node), colors, cat = pulp.LpBinary) for node in nodes } # 1つの領域は一色でしか塗らない for node in nodes: problem += lpSum(var[node].values()) == 1 # 隣り合った領域は同色で塗らない for node1, node2 in edges: for color in colors: problem += var[node1][color] + var[node2][color] <= 1 start = time.time() if solver == 'cbc': result = problem.solve() elif solver == 'cplex': result = problem.solve(CPLEX(msg=True, mip=True)) elif solver == 'gurobi': result = problem.solve(GUROBI(msg=True, mip=True, Threads=threads)) elapsed_time = time.time() - start print('elapsed_time :', elapsed_time) print('result : '+ pulp.LpStatus[result]) if pulp.LpStatus[result] == 'Optimal': print('value =', pulp.value(problem.objective)) output = {} for node, v in var.items(): for color, flg in v.items(): if flg.value() == 1: output[node] = color break if plot: plot_gc(G, output, pos)
def _selectSentences(self, wordlimit): """ Optimally selects the sentences based on their bigrams """ fullsentences = [ removePOS(sentence) for cluster in self.candidates for sentence in cluster ] # remember the correspondance between a sentence and its cluster clusternums = {} sentencenums = {s: i for i, s in enumerate(fullsentences)} for i, cluster in enumerate(self.candidates): clusternums[i] = [] for sentence in cluster: fullsentence = removePOS(sentence) if fullsentence in sentencenums: clusternums[i].append(sentencenums[removePOS(sentence)]) # extract bigrams for all sentences bigramssentences = [ extractBigrams(sentence.split()) for sentence in fullsentences ] # get uniqs bigrams uniqbigrams = set(bigram for sentence in bigramssentences for bigram in sentence) numbigrams = len(uniqbigrams) numsentences = len(fullsentences) # rewrite fullsentences fullsentences = [wellformatize(sentence) for sentence in fullsentences] # filter out rare bigrams weightedbigrams = { bigram: (count if count >= self.minbigramcount else 0) for bigram, count in self.bigramstats.items() } problem = pulp.LpProblem("Sentence selection", pulp.LpMaximize) # concept variables concepts = pulp.LpVariable.dicts(name='c', indexs=range(numbigrams), lowBound=0, upBound=1, cat='Integer') sentences = pulp.LpVariable.dicts(name='s', indexs=range(numsentences), lowBound=0, upBound=1, cat='Integer') # objective : maximize wi * ci (weighti * concepti) # small hack. If the bigram has been filtered out from uniqbigrams, # we give it a weight of 0. problem += sum([(weightedbigrams.get(bigram) or 0) * concepts[i] for i, bigram in enumerate(uniqbigrams)]) # constraints # size problem += sum([ sentences[j] * len(fullsentences[j].split()) for j in range(numsentences) ]) <= wordlimit # integrity constraints (link between concepts and sentences) for j, bsentence in enumerate(bigramssentences): for i, bigram in enumerate(uniqbigrams): if bigram in bsentence: problem += sentences[j] <= concepts[i] for i, bigram in enumerate(uniqbigrams): problem += sum([ sentences[j] for j, bsentence in enumerate(bigramssentences) if bigram in bsentence ]) >= concepts[i] # select only one sentence per cluster for clusternum, clustersentences in clusternums.items(): problem += sum([sentences[j] for j in clustersentences]) <= 1 # solve the problem problem.solve(GLPK()) summary = [] # get the sentences back for j in range(numsentences): if sentences[j].varValue == 1: summary.append(fullsentences[j]) return summary
def Objective(): problem = pulp.LpProblem() index = list(range(9)) x = [[[pulp.LpVariable(f'x{i}{j}{k}', cat='Binary') for k in index] for j in index] for i in index] return problem, index, x
# import the library pulp as p import pulp as p # Create a LP Minimization problem Lp_prob = p.LpProblem('Problem', p.LpMinimize) # Create problem Variables R1 = p.LpVariable("R1", lowBound = 0) R2 = p.LpVariable("R2", lowBound = 0) R3 = p.LpVariable("R3", lowBound = 0) R4 = p.LpVariable("R4", lowBound = 0) I1 = p.LpVariable("I1", lowBound = 0) I2 = p.LpVariable("I2", lowBound = 0) I3 = p.LpVariable("I3", lowBound = 0) I4 = p.LpVariable("I4", lowBound = 0) B1 = p.LpVariable("B1", lowBound = 0) B2 = p.LpVariable("B2", lowBound = 0) B3 = p.LpVariable("B3", lowBound = 0) B4 = p.LpVariable("B4", lowBound = 0) S1 = p.LpVariable("S1", lowBound = 0) S2 = p.LpVariable("S2", lowBound = 0) S3 = p.LpVariable("S3", lowBound = 0) S4 = p.LpVariable("S4", lowBound = 0) D1 = p.LpVariable("D1", lowBound = 0) D2 = p.LpVariable("D2", lowBound = 0) D3 = p.LpVariable("D3", lowBound = 0) D4 = p.LpVariable("D4", lowBound = 0) C1 = p.LpVariable("C1", lowBound = 0) C2 = p.LpVariable("C2", lowBound = 0) C3 = p.LpVariable("C3", lowBound = 0) C4 = p.LpVariable("C4", lowBound = 0)
def setup_lp(self, reserve=True, proportion=True, combined=True, transmission=True): """ Set up the Linear Program by creating an objective function and passing the requisite variables to it. Creates the linear program according to simplified SPD model """ # Get the Constraints and lists for model creation simplification eb = self.ISO.energy_bands rb = self.ISO.reserve_bands tb = self.ISO.transmission_bands nd = self.ISO.all_nodes et = self.ISO.energy_totals rt = self.ISO.reserve_totals tt = self.ISO.transmission_totals ebmap = self.ISO.energy_band_map rbmap = self.ISO.reserve_band_map tbmap = self.ISO.transmission_band_map ebp = self.ISO.energy_band_prices rbp = self.ISO.reserve_band_prices ebm = self.ISO.energy_band_maximum rbm = self.ISO.reserve_band_maximum tbm = self.ISO.transmission_band_maximum etm = self.ISO.energy_total_maximum ttm = self.ISO.transmission_total_maximum rbpr = self.ISO.reserve_band_proportion spin = self.ISO.spinning_station_names spin_map = self.ISO.spin_map node_map = self.ISO.node_energy_map demand = self.ISO.node_demand node_t_map = self.ISO.node_t_map td = self.ISO.node_transmission_direction rzones = self.ISO.reserve_zone_names rzone_g = self.ISO.reserve_zone_generators rzone_t = self.ISO.reserve_zone_transmission rztd = self.ISO.reserve_zone_trans_direct rz_providers = self.ISO.reserve_zone_reserve # Set up the linear program self.lp = lp.LpProblem("Model Dispatch", lp.LpMinimize) # Add variables ebo = lp.LpVariable.dicts("Energy_Band", eb, 0) rbo = lp.LpVariable.dicts("Reserve_Band", rb, 0) tbo = lp.LpVariable.dicts("Transmission_Band", tb) eto = lp.LpVariable.dicts("Energy_Total", et, 0) rto = lp.LpVariable.dicts("Reserve_Total", rt, 0) tto = lp.LpVariable.dicts("Transmission_Total", tt) node_inj = lp.LpVariable.dicts("Nodal_Inject", nd) risk = lp.LpVariable.dicts("Risk", rzones) # Map the add Constraint method to a simpler string addC = self.lp.addConstraint SUM = lp.lpSum # Objective function self.lp.setObjective(SUM([ebo[i] * ebp[i] for i in eb]) +\ SUM([rbo[j] * rbp[j] for j in rb])) # Begin Adding Constraint # Nodal Dispatch for n in nd: n1 = '_'.join([n, 'Energy_Price']) n2 = '_'.join([n, 'Nodal_Transmission']) addC(node_inj[n] == SUM([eto[i] for i in node_map[n]]) - demand[n], n1) addC( node_inj[n] == SUM([tto[i] * td[n][i] for i in node_t_map[n]]), n2) # Individual Band Offer for i in eb: name = '_'.join([i, 'Band_Energy']) addC(ebo[i] <= ebm[i], name) # Reserve Band Offer for j in rb: name = '_'.join([j, 'Band_Reserve']) addC(rbo[j] <= rbm[j], name) # Transmission band Offer for t in tb: addC(tbo[t] <= tbm[t]) addC(tbo[t] >= tbm[t] * -1) # Energy Total Offer for i in et: name = '_'.join([i, 'Total_Energy']) addC(SUM([ebo[j] for j in ebmap[i]]) == eto[i], name) # Reserve Total Offer for i in rt: name = '_'.join([i, 'Total_Reserve']) addC(SUM([rbo[j] for j in rbmap[i]]) == rto[i], name) # Transmission Total offer for i in tt: addC(SUM([tbo[j] for j in tbmap[i]]) == tto[i]) addC(tto[i] <= ttm[i]) addC(tto[i] >= ttm[i] * -1) # Spinning Reserve Constraints for i in spin: name = '_'.join([i, 'Combined_Dispatch']) addC(rto[i] + eto[i] <= etm[i], name) for j in spin_map[i]: name = '_'.join([j, 'Prop']) addC(rbo[j] <= rbpr[j] * eto[i], name) # Risk Constraints for r in rzones: # Generation Risk for i in rzone_g[r]: name = '_'.join([r, i]) addC(risk[r] >= eto[i], name) # Transmission Risk for t in rzone_t[r]: name = '_'.join([r, t]) addC(risk[r] >= tto[t] * rztd[r][t], name) # Reserve Dispatch for r in rzones: n1 = '_'.join([r, 'Reserve_Price']) addC(SUM(rto[i] for i in rz_providers[r]) - risk[r] >= 0., n1)
def _solver(Gt, Gd, target_latency=None): """ Args: target_latency (int): latency constrain for this task graph source_list (list): source nodes in the task graph dst_list (list): destination nodes in the task graph Gt (networkx.DiGraph): task graph in a multi-source, single destination, no-loop directed graph, where src_k are data sources, dst is the actuator, and other nodes in between are tasks src1 -----> t11 -----> t12 ... -----> dst src2 -----> t21 -----> t22 ... -----> ... ... ... ... -----> tk1 -----> tk2 ... -----> Gt.node[t] (dict): node, stores information of each task Gt[t1][t2] (dict): edge, stores relationship between tasks E(t1, t2) (Unit): input/output relationship between t1, t2 If t1 will not ouput any data to t2, set the value to 0 e.g. Gt[t1][t2][GtInfo.TRAFFIC] = Unit.byte(20) Gt[t1][t2][GtInfo.TRAFFIC] = 0 _It(t2) (Unit): total input data size to the task. Obtained from sum E(ti, t2) for all ti with an edge to t2. The value will be stored at Gt.node[t][GtInfo.RESRC_RQMT] _Ot(t1) (Unit): total ouput data size to the task. Obtained from sum E(t1, ti) for all ti with an edge from t1. The value will be stored at Gt.node[t][GtInfo.RESRC_RQMT] Lt(t,d) (Unit): computation latency of task t runs on device d. Devices can be categorized according to number of CPUs, GPUs, RAM size, and disk space. e.g. Gt.node[t][GtInfo.LATENCY_INFO] = { Device.T2_MICRO: Unit.ms(100), Device.P3_2XLARGE: Unit.ms(5)} device_type = Device.type(Gd.node[d][GdInfo.HARDWARE]) Gt.node[t][GtInfo.LATENCY_INFO][device_type] = 100 (ms) Rt(t) (dict): minimum RESRC requirement for task t Rt(t,r,d): minimum requirement of RESRC r for task t of a specific build flavor for that device e.g. build_type = Flavor.type(Device.P3_2XLARGE) assert(build_type == Flavor.GPU) Gt.node[t][GtInfo.RESRC_RQMT][build_type] = { Hardware.RAM: Unit.gb(2), Hardware.HD: Unit.mb(512), Hardware.CPU: Unit.percentage(10), Hardware.GPU: Unit.percentage(60), Hardware.CAMERA: 1, Hardware.NIC_INGRESS: Unit.mb(2), # _It(t) Hardware.NIC_EGRESS: Unit.byte(20), # _Ot(t) } Gd (networkx.DiGraph): a directed graph describes network topology, where each node represent a device Gd[d] (dict): information of each device, including: Ld(d1, d2) (Unit): transmission time between two devices d1, d2 If d2 is not reachable from d1, set the value to MAXINT e.g. Gd[d1][d2][GdInfo.LATENCY] = 20 (ms) Gd[d1][d2][GdInfo.LATENCY] = Const.MAXINT _Hd(d) (dict): hardware specification of device d. Use this internal information to determine device_type Dd(t) and calculate Rd(d). e.g. Gd.node[d][GdInfo.HARDWARE] = { Hardware.RAM: Unit.gb(16), Hardware.HD: Unit.tb(1), Hardware.CPU: 4, Hardware.GPU: 1, Hardware.GPS: 1, Hardware.CAMERA: 1 Hardware.NIC_INGRESS: Unit.gbps(10), Hardware.NIC_EGRESS: Unit.gbps(10), } _Dd(d) (enum): device type of device d, determined by hardware specification of the device. Used by Gt.node[t] for accessing information of the a certain device type e.g. device_type = Device.type(Gd.node[d][GdInfo.HARDWARE]) assert(device_type == Device.T2_MICRO) Rd(d) (dict): available RESRCs on device d. Rd(d, r) (Unit): availablity of RESRC r on device d. e.g. Gd.node[d][GdInfo.RESRC] = { Hardware.RAM: Unit.gb(12), Hardware.HD: Unit.gb(500), Hardware.CPU: Unit.percentage(80), Hardware.GPU: Unit.percentage(100), Hardware.BW_INGRESS: Unit.mb(100), Hardware.BW_EGRESS: Unit.mb(60), Hardware.GPS: 1, Hardware.PROXIMITY: 1, Hardware.ACCELEROMETER: 1, Hardware.GYROSCOPE: 1, Hardware.CAMERA: 1, } decision variable: X(t,d) = 1 if assign task t to device d else 0 objective: minimize longest path's overall latency in the task graph, i.e. total execution times + transmission latencies along the path len(p) minimize max { sum ( X(ti,di) * Lt(ti, di) ) X(t,d) p in Gt i=1 len(p)-1 + sum ( X(ti,di) * X(ti+1,di+1) * Ld(di, di+1) ) } i=1 this can be simplified by an auxiliary variable and rewrote as: minimize Y , where Y = max {....} above with additional constrains: for p in Gt: len(p) Y >= max { sum ( X(ti,di) * Lt(ti, di) ) p in Gt i=1 len(p)-1 + sum ( X(ti,di) * X(ti+1,di+1) * Ld(di, di+1) ) } i=1 constrians 1: neighbors in the task graph must also be accessible from each other in network graph for (ti, tj) in Gt.edges(): for all combinations (di, dj) in Gd: X(ti,di) * X(tj,dj) * Ld(di, dj) < LATENCY_MAX constrians 2: device must be able to support what the tasks need for d in Gd: for r in Rd: len(Gt) Rd(d,r) - { sum ( X(ti,d) * Rt(ti,r,d) ) } >= 0 i=1 constrains 3: task -> device is one-to-one mapping, and all task must be mapped to one device since linear programming cannot have variable multiplication, use a helper variable XX to replace X(ti,di) * X(tj,dj) X(ti,di) * X(tj,dj) ---replace---> XX(X(ti,di),X(tj,dj)) with additional constrains XX(X(ti,di),X(tj,dj)) + 1 >= X(ti,di) + X(tj,dj) XX(X(ti,di),X(tj,dj)) * 2 <= X(ti,di) + X(tj,dj) """ # define invalid_latency as a constrain to filter out meaningless # solutions if target_latency: invalid_latency = target_latency * 2 else: invalid_latency = Const.INT_MAX log.info( ('set invalid_latency={latency}. skip neighbors cannot be reached ' 'within {latency} ms.').format(latency=invalid_latency)) # Generate all possible mappings of device_i <-> task_i known_mapping = {} for node in Gt.nodes(): mapped_device = Gt.node[node].get(GtInfo.DEVICE, None) if mapped_device is not None: known_mapping[node] = mapped_device log.info('known_mapping: {}'.format(known_mapping)) mapped_tasks = list(known_mapping) mapped_devices = listvalues(known_mapping) tasks = [t for t in Gt.nodes() if t not in mapped_tasks] devices = [d for d in Gd.nodes() if d not in mapped_devices] log.info('find possible mappings for {} tasks in {} devices'.format( len(tasks), len(devices))) # create LP problem prob = pulp.LpProblem("placethings", pulp.LpMinimize) # auxiliary variable: it represent the longest path's overall latency # in the task graph Y = pulp.LpVariable('LongestPathLength', lowBound=0, upBound=Const.INT_MAX, cat='Interger') # objective: minimize longest path's overall latency in the task graph # later, add additional constrains for the auxiliary variable prob += Y # decision variable: X(t,d) = 1 if assign task t to device d else 0 X = defaultdict(dict) all_unknown_X = [] for t in tasks: for d in devices: X[t][d] = None for d in mapped_devices: for t in Gt.nodes(): X[t][d] = 0 for t in mapped_tasks: for d in Gd.nodes(): X[t][d] = 0 d_known = Gt.node[t][GtInfo.DEVICE] X[t][d_known] = 1 #Mapping which are added by user for t in tasks: for d in devices: if X[t][d] is None: X[t][d] = pulp.LpVariable('X_{}_{}'.format(t, d), lowBound=0, upBound=1, cat='Integer') all_unknown_X.append(X[t][d]) # 1-1 map # One task can only map map to device prob += pulp.lpSum(listvalues(X[t])) == 1 # number of X == 1 must equal to number of tasks log.info('there are {} unknowns'.format(len(all_unknown_X))) assert len(all_unknown_X) == len(tasks) * len(devices) # tasks are the tasks not yet assigned. # devices are the devices not yet mapped prob += pulp.lpSum(all_unknown_X) == len(tasks) # auxiliary variable: use XX to replace X[ti][di] * X[tj][dj] XX = defaultdict(dict) all_XX = [] for ti in Gt.nodes(): for di in Gd.nodes(): for tj in Gt.nodes(): for dj in Gd.nodes(): if (ti, tj) not in Gt.edges(): XX[(ti, di)][(tj, dj)] = 0 elif (di, dj) not in Gd.edges() or ( Gd[di][dj][GdInfo.LATENCY] > invalid_latency): # constrians 1: neighbors in the task graph must also # be accessible from each other in the network graph XX[(ti, di)][(tj, dj)] = 0 else: XX[(ti, di)][(tj, dj)] = pulp.LpVariable('XX_{}_{}'.format( (ti, di), (tj, dj)), lowBound=0, upBound=1, cat='Integer') all_XX.append(XX[(ti, di)][(tj, dj)]) # add constrains prob += (XX[(ti, di)][(tj, dj)] + 1 >= X[ti][di] + X[tj][dj]) prob += (XX[(ti, di)][(tj, dj)] * 2 <= X[ti][di] + X[tj][dj]) log.info('there are {} combinations for links'.format(len(all_XX))) prob += pulp.lpSum(all_XX) == len(Gt.edges()) # Generate all simple paths in the graph G from source to target. src_list, dst_list, all_paths = _find_all_simple_path(Gt) log.info('find all path from {} to {}'.format(src_list, dst_list)) # Generate all possible mappings all_mappings = list(pulp.permutation(devices, len(tasks))) log.info('{} possible mappings for {} devices and {} tasks'.format( len(all_mappings), len(devices), len(tasks))) task_to_idx = dict(zip(tasks, range(len(tasks)))) # use constrains to model Y, the longest path for each mapping for device_mapping in all_mappings: for path in all_paths: assert path[0] in src_list assert path[len(path) - 1] in dst_list path_vars = [] # first node: src ti = path[0] di = Gt.node[ti][GtInfo.DEVICE] # device_mapping start from path[1] to path[N-1] for j in range(1, len(path) - 1): tj = path[j] dj = device_mapping[task_to_idx[tj]] assert Gt.node[tj][GtInfo.DEVICE] is None assert dj in Gd.nodes() # get transmission latency from di -> dj Ld_di_dj = Gd[di][dj][GdInfo.LATENCY] # path_vars.append((X[ti][di] * X[tj][dj]) * Ld_di_dj) path_vars.append(XX[(ti, di)][(tj, dj)] * Ld_di_dj) log.debug('Ld_di_dj (move from {} to {}) = {}'.format( di, dj, Ld_di_dj)) # get computation latency for task tj at dj dj_type = Gd.node[dj][GdInfo.DEVICE_TYPE] # get latency of the default build flavor Lt_tj_dj = listvalues( Gt.node[tj][GtInfo.LATENCY_INFO][dj_type])[0] path_vars.append(X[tj][dj] * Lt_tj_dj) log.debug('Lt_tj_dj (compute {} at {}) = {}'.format( tj, dj, Lt_tj_dj)) ti = tj di = dj # last node: dst tj = path[len(path) - 1] dj = Gt.node[tj][GtInfo.DEVICE] Ld_di_dj = Gd[di][dj][GdInfo.LATENCY] # path_vars.append(X[ti][di] * X[tj][dj] * Ld_di_dj) path_vars.append(XX[(ti, di)][(tj, dj)] * Ld_di_dj) log.debug('Ld_di_dj (move from {} to {}) = {}'.format( di, dj, Ld_di_dj)) log.debug('add constrain for path:\n Y >= {}'.format(path_vars)) # add constrain prob += Y >= pulp.lpSum(path_vars) # constrians 2: device must be able to support what the tasks need # for d in Gd: # for r in Rd: # len(Gt) # Rd(d,r) - { sum ( X(ti,d) * Rt(ti,r,d) ) } >= 0 # i=1 for di in devices: for resrc in Hardware: # get available RESRC or set to 0 Rd_d_r = Gd.node[di][GdInfo.RESRC].get(resrc, 0) var_list = [] for ti in tasks: di_type = Gd.node[di][GdInfo.DEVICE_TYPE] # get the default flavor ti_flavor = list(Gt.node[ti][GtInfo.LATENCY_INFO][di_type])[0] Rt_t_r_d = (Gt.node[ti][GtInfo.RESRC_RQMT][ti_flavor].get( resrc, 0)) if Rt_t_r_d > 0: var_list.append(X[ti][di] * Rt_t_r_d) if var_list: log.debug('add constrain for {}({}):\n {} <= {}'.format( di, resrc, var_list, Rd_d_r)) prob += pulp.lpSum(var_list) <= Rd_d_r # solve status = prob.solve(pulp.solvers.GLPK(msg=1)) log.info('status={}'.format(pulp.LpStatus[status])) result_mapping = {} for t in Gt.nodes(): for d in Gd.nodes(): if pulp.value(X[t][d]): log.info('map: {} <-> {}, X_t_d={}'.format( t, d, pulp.value(X[t][d]))) result_mapping[t] = d return status, result_mapping
def build_local_problem_lp(pb, name): lp = pulp.LpProblem(name + ".lp", pulp.LpMinimize) lp.setSolver() prod_vars = {} in_use_vars = {} defaillance = {} cout_proportionnel_defaillance = 3000 #euros/MWh #demande = demande-auto_conso #auto_conso<=Enr #Enr=Enr-auto_conso #inject= for t in pb.time_steps: prod_vars[t] = {} in_use_vars[t] = {} var_name = "battery_stock" + str(t) prod_vars[t]["battery_stock"] = pulp.LpVariable( var_name, 0.0, pb.battery.energy_max) var_name = "battery_store" + str(t) prod_vars[t]["battery_store"] = pulp.LpVariable( var_name, -pb.battery.power_max_store, 0.0) var_name = "battery_prod" + str(t) prod_vars[t]["battery_prod"] = pulp.LpVariable( var_name, 0.0, pb.battery.power_max_prod) cnt_name = "cnt_storage_evolution_" + str(t) if t == pb.time_steps[0]: #initial stock=0 lp += prod_vars[t][ "battery_stock"] == pb.time_step_duration / 60.0 * ( -pb.battery.efficiency * prod_vars[t]["battery_store"] - prod_vars[t]["battery_prod"]), cnt_name else: lp += prod_vars[t]["battery_stock"] == prod_vars[ t - 1]["battery_stock"] + pb.time_step_duration / 60.0 * ( -pb.battery.efficiency * prod_vars[t]["battery_store"] - prod_vars[t]["battery_prod"]), cnt_name var_name = "auto_conso_" + str(t) prod_vars[t]["auto_conso"] = pulp.LpVariable(var_name, 0.0, pb.local_demand[t]) var_name = "payed_" + str(t) prod_vars[t]["payed_conso"] = pulp.LpVariable(var_name, 0.0, pb.local_demand[t]) var_name = "sold_local_production" + str(t) prod_vars[t]["sold_local_production"] = pulp.LpVariable( var_name, 0.0, pb.local_solar_power[t] + pb.battery.power_max_prod) lp += prod_vars[t]["auto_conso"] + prod_vars[t][ "payed_conso"] == pb.local_demand[t], "cnt_local_conso_" + str(t) lp += prod_vars[t][ "sold_local_production"] == pb.local_solar_power[t] - prod_vars[t][ "auto_conso"] + prod_vars[t]["battery_prod"] + prod_vars[t][ "battery_store"], "cnt_local_solar_" + str(t) lp.setObjective( pb.electricity_tariff*pulp.lpSum([prod_vars[t]["payed_conso"] for t in pb.time_steps])* pb.time_step_duration/60.0\ -pulp.lpSum([pb.solar_power_selling_price_chronicle[t]*prod_vars[t]["sold_local_production"] for t in pb.time_steps]) * pb.time_step_duration/60.0) model = Model(lp, prod_vars) return model
def run(total, price): y = [None] * len(price) names = [p[1] for p in price] problem = pulp.LpProblem("Problem-1", pulp.LpMinimize) for index in range(len(price)): y[index] = pulp.LpVariable("y" + str(index), 0, 2, pulp.LpInteger) # problem += pulp.lpSum([y[i] for i in range(len(price))]), "The number of items" prices = [y[i] * price[i][0] for i in range(len(price))] # prices = [y[i] * price[i] for i in range(len(price))] problem += total - pulp.lpSum(prices), "Use as much" problem += total == pulp.lpSum(prices), "Use exact" problem += pulp.lpSum(prices) <= total, "Do not over" for index in range(len(price)): if len(price[index]) >= 4: # Set minimum problem += y[index] >= price[index][3] if len(price[index]) >= 3: # Set maximum problem += y[index] <= price[index][2] # 問題の式全部を表示 print("問題の式") print("--------") print(problem) print("--------") print(price) # 計算 result_status = problem.solve() # (解が得られていれば)目的関数値や解を表示 if pulp.LpStatus[result_status] != "Optimal": print("解なし") return {"ok": False} else: obj = pulp.value(problem.objective) if obj != 0: print("解無し 残額: %d" % (obj)) return {"ok": False} else: print("") print("計算結果") print("********") print("最適性 = {}".format(pulp.LpStatus[result_status])) print("目的関数値 = {}".format(obj)) print("y = {}".format([int(pulp.value(v)) for v in y])) print("********") print(" ", price) used = 0 for i, v in enumerate(zip(price, [int(pulp.value(v)) for v in y])): p, n = v if n > 0: print("{}\t{}\t{}\t{}".format(i, p[0], n, p[1])) used += p[0] * n print("Total: ", used) count = {names[i]: int(pulp.value(y[i])) for i in range(len(y))} return {"ok": True, "count": count}
ProdCosts = common.readArrayFromFile('prod_costs.dat') # NOTE(nox): Indices Fact = range(0, len(Capacity)) Cent = range(0, len(Demand)) # NOTE(nox): Decision variables Dist = pulp.LpVariable.dicts('Distribution', [(F, C) for F in Fact for C in Cent], cat=pulp.LpInteger, lowBound=0) Used = pulp.LpVariable.dicts('Factory used', [F for F in Fact], cat=pulp.LpBinary) # NOTE(nox): Objective function Model = pulp.LpProblem('Costs', pulp.LpMinimize) Model += (sum(DistCosts[C][F] * Dist[(F, C)] for F in Fact for C in Cent) + sum(FixedCosts[F] * Used[F] for F in Fact) + sum(ProdCosts[F] * sum(Dist[(F, C)] for C in Cent) for F in Fact)) # NOTE(nox): Subject to for F in Fact: Model += sum(Dist[(F, C)] for C in Cent) <= Capacity[F] * Used[F] for C in Cent: Model += sum(Dist[(F, C)] for F in Fact) >= Demand[C] Model += Used[0] == 1 # NOTE(nox): Solve Status = Model.solve()
import pulp x = pulp.LpVariable('Nb of tables', lowBound=10, upBound=20, cat='Integer') z = pulp.LpProblem('My maximization pb', pulp.LpMaximize) z += 5 * x, 'Net Profit' z += x <= 15, 'max of daily production' z.solve() for var in z.variables(): print(var.name + '=' + str(var.varValue)) print('value of Obj function:' + str(pulp.value(z.objective)))
def values(xs: List[pulp.pulp.LpAffineExpression]) -> ndarray: return array([x.value() for x in xs]) def accumulate(var, i) -> pulp.pulp.LpAffineExpression: return pulp.lpSum([var[k] for k in range(i + 1)]) # Solution: total_days = len(purchases_a) assert len(purchases_a) == len(purchases_b) days = [i for i in range(total_days)] model = pulp.LpProblem("Planning Problem", pulp.LpMinimize) # Declare variables xa = pulp.LpVariable.dicts("Production Product A", days, lowBound=0, upBound=max_output_a) xb = pulp.LpVariable.dicts("Production Product B", days, lowBound=0, upBound=max_output_b) requirement_b = purchases_b requirement_a = array([xb[d] for d in days]) * requirement_b_to_a + purchases_a # Closed sum (zero inventory at start or end)
def blocked_reactions_analysis( database, pulp_solver, specific_bounds, custom_flux_constraints, excluded_reactions=None, target_reactions_list=None, logger=None): """ Perform flux variability analysis on the database, based on the overall reaction equation of optstoic. If a reaction cannot carry flux (i.e., -eps <= v(j) <= eps, where eps = 1e-8), then the reaction is considered as a blocked reaction. The blocked reactions are then eliminated from the database S matrix. Next, the internal loops (excluding cofactors) are identified. Then, optStoic analysis can be performed for pathway prospecting. max/min v(j) subject to: sum(j, S(i,j) * v(j)) = 0, for all i custom_flux_constraints Note: The glycolysis study was done using the GAMS version of this code. This is written in attempt to port find_blocked_reactions.gms from GAMS to Python, as a part of effort to generalize optstoic analysis. Args: database (:obj:`BaseReactionDatabase`): The default reaction database without blocked reactions/loops. pulp_solver (TYPE): The solver for PuLP. specific_bounds (dict): LB and UB for exchange reactions which defined the overall design equations. E.g. {'Ex_glc': {'LB': -1, 'UB':-1}} custom_flux_constraints (TYPE): The custom constraints that need to be added to the model formulation. excluded_reactions (None, optional): The list of reactions that are manually selected to be excluded from optstoic solution. target_reactions_list (None, optional): If provided, the blocked reaction analysis is performed only on a subset of the reaction provided. If None, the blocked reaction analysis will be performed on all reactions in the database. The excluded_reactions set can be subtracted(e.g., set(database.reactions) - excluded_reactions), since they are blocked reactions. logger (:obj:`logging.logger`, optional): The logging instance Returns: TYPE: Description Raises: ValueError: Description Deleted Parameters: user_defined_export_rxns_Sji (dict): The list of export reactions that need to be added to the model for metabolite exchange (i.e., any metabolite that participate in the design equation) """ if logger is None: logger = create_logger( name="optstoicpy.script.database_preprocessing.blocked_reactions_analysis") logger.warning( "This process may take a long time to run. It is recommended to be run in a batch script.") M = 1000 EPS = 1e-8 # Initialize variables v = pulp.LpVariable.dicts("v", database.reactions, lowBound=-M, upBound=M, cat='Continuous') for j in database.reactions: if database.rxntype[j] == 0: # Forward irreversible v[j].lowBound = 0 v[j].upBound = M elif database.rxntype[j] == 1: # Reversible v[j].lowBound = -M v[j].upBound = M elif database.rxntype[j] == 2: # Reverse irreversible v[j].lowBound = -M v[j].upBound = 0 elif database.rxntype[j] == 4: v[j].lowBound = 0 v[j].upBound = 0 else: raise ValueError("Reaction type for reaction %s is unknown." % j) if excluded_reactions is not None: for j in excluded_reactions: v[j].lowBound = 0 v[j].upBound = 0 # Fix stoichiometry of source/sink metabolites for j, bounds in specific_bounds.items(): v[j].lowBound = bounds['LB'] v[j].upBound = bounds['UB'] FVA_res = {} blocked_reactions = [] lp_prob = None if target_reactions_list is None: target_reactions_list = database.reactions num_rxn = len(target_reactions_list) for ind, j1 in enumerate(target_reactions_list): logger.debug("%s/%s" % (ind, num_rxn)) FVA_res[j1] = {} for obj in ['min', 'max']: # Variables (make a copy) vt = copy.deepcopy(v) del lp_prob # Objective function if obj == 'min': lp_prob = pulp.LpProblem("FVA%s" % obj, pulp.LpMinimize) lp_prob += vt[j1], "FVA_min" elif obj == 'max': lp_prob = pulp.LpProblem("FVA%s" % obj, pulp.LpMaximize) lp_prob += vt[j1], "FVA_max" # Constraints # Mass_balance for i in database.metabolites: # If metabolites not involve in any reactions if i not in database.S: continue label = "mass_balance_%s" % i dot_S_v = pulp.lpSum([database.S[i][j] * vt[j] for j in list(database.S[i].keys())]) condition = dot_S_v == 0 lp_prob += condition, label if custom_flux_constraints is not None: logger.info("Adding custom constraints...") for group in custom_flux_constraints: lp_prob += pulp.lpSum(vt[rxn] for rxn in group['reactions'] ) <= group['UB'], "%s_UB" % group['constraint_name'] lp_prob += pulp.lpSum(vt[rxn] for rxn in group['reactions'] ) >= group['LB'], "%s_LB" % group['constraint_name'] lp_prob.solve(solver=pulp_solver) FVA_res[j1][obj] = pulp.value(lp_prob.objective) if (FVA_res[j1]['max'] < EPS) and (FVA_res[j1]['min'] > -EPS): blocked_reactions.append(j1) json.dump(FVA_res, open("temp_FVA_result.json", 'w+'), sort_keys=True, indent=4) return blocked_reactions, FVA_res
import pulp pr = pulp.LpProblem("Farm_ngnt.problem", pulp.LpMaximize) x = pulp.LpVariable("x", lowBound=0) y = pulp.LpVariable("y", lowBound=0) pr += x + y <= 30 pr += 0.5*x + 0.1*y <= 6 pr += 100*x + 50*y pr.solve() print("x=", str(x.value()), "y=", str(y.value()))
def sign(agent_id: str, agreements: List[Contract], trust_probabilities: Dict[str, float], inventory: int): """ Given a list of agreements and trust probabilities, each of type negmas.Contract, decides which agreements to sign. :param agent_id: the agent's id (self.id of the calling agent) :param agreements: a list of agreements, each of type negmas.Contracts. :param trust_probabilities: a dictionary mapping an agent's id to its trust probability :return: a dictionary with information about the solver. In particular, the dictionary contains an entry 'list_of_signatures' which is a list of the same length as the input list of agreements. The i-th element of the list 'list_of_signatures' is self.id/None in case the agent wants/do not wants to sign the i-th agreement in the input list. """ # If the list of agreements is empty, then return an empty list of signatures. if len(agreements) == 0: return { 'list_of_signatures': [], 'agent_id': agent_id, 'model': None, 'time_to_generate_ilp': None, 'time_to_solve_ilp': None, 'agreements': agreements, 'trust_probabilities': trust_probabilities, 'profit': None } # Partition agreements into buy and sell agreements. agreements_to_buy_inputs, agreements_to_sell_outputs = SCMLContractsSigner.partition_agreements( agent_id, agreements, trust_probabilities) # If there are no sell contracts, the signer has nothing to do and signs nothing. if len(agreements_to_sell_outputs) == 0: return { 'list_of_signatures': [None] * len(agreements), 'agent_id': agent_id, 'model': None, 'time_to_generate_ilp': None, 'time_to_solve_ilp': None, 'agreements': agreements, 'trust_probabilities': trust_probabilities, 'profit': None } # For efficiency purposes, we order the agreements by delivery times. But, before we do, we must be able to # recover the indices of the agreements as given to the solver, otherwise, we can't map the output to the right agreements. buy_agreements = [ agreement + (i, ) for i, agreement in enumerate(agreements_to_buy_inputs) ] sell_agreements = [ agreement + (i, ) for i, agreement in enumerate(agreements_to_sell_outputs) ] # At this point an agreement is a tuple: (MASTER_INDEX, QUANTITY, TIME, PRICE, SUB_INDEX). Now we order by TIME. buy_agreements = sorted(buy_agreements, key=lambda x: x[SCMLContractsSigner.TIME]) sell_agreements = sorted(sell_agreements, key=lambda x: x[SCMLContractsSigner.TIME]) # The code that follows will change the agreement lists, so we make a copy of them for later reference. buy_agreements_copy = buy_agreements.copy() sell_agreements_copy = sell_agreements.copy() t0 = time.time() # Decision variables buy_sign_vars = pulp.LpVariable.dicts( 'buy_sign', (i for i, _ in enumerate(buy_agreements)), lowBound=0, upBound=1, cat='Integer') sell_sign_vars = pulp.LpVariable.dicts( 'sell_sign', (i for i, _ in enumerate(sell_agreements)), lowBound=0, upBound=1, cat='Integer') # Generate the pulp problem. model = pulp.LpProblem('Contract_Signer_Solver', pulp.LpMaximize) # The objective function is profit, defined as revenue minus cost. model += pulp.lpSum([ sell_agreements[i][SCMLContractsSigner.QUANTITY] * sell_agreements[i][SCMLContractsSigner.PRICE] * sell_agreements[i][SCMLContractsSigner.PARTNER_TRUST] * sell_sign_vars[s[SCMLContractsSigner.SUB_INDEX]] for i, s in enumerate(sell_agreements) ] + [ -1.0 * buy_agreements[i][SCMLContractsSigner.QUANTITY] * buy_agreements[i][SCMLContractsSigner.PRICE] * buy_agreements[i][SCMLContractsSigner.PARTNER_TRUST] * buy_sign_vars[b[SCMLContractsSigner.SUB_INDEX]] for i, b in enumerate(buy_agreements) ]) # Construct the constraints. The constraint model inventory feasibility, i.e., we don't commit to a sell unless we have enough outputs. current_sell_time = sell_agreements[0][SCMLContractsSigner.TIME] current_sell_time_sum = [] partial_sell_sum = [] partial_buy_sum = [] result = [] while len(sell_agreements) > 0: s = sell_agreements.pop(0) if current_sell_time == s[SCMLContractsSigner.TIME]: current_sell_time_sum += [ sell_sign_vars[s[SCMLContractsSigner.SUB_INDEX]] * s[SCMLContractsSigner.QUANTITY] ] else: partial_buy_sum += SCMLContractsSigner.constraints_generation_helper( buy_agreements, buy_sign_vars, current_sell_time) result += [(current_sell_time_sum.copy(), partial_buy_sum.copy(), partial_sell_sum.copy())] partial_sell_sum += current_sell_time_sum current_sell_time = s[SCMLContractsSigner.TIME] current_sell_time_sum = [ sell_sign_vars[s[SCMLContractsSigner.SUB_INDEX]] * s[SCMLContractsSigner.QUANTITY] ] partial_buy_sum += SCMLContractsSigner.constraints_generation_helper( buy_agreements, buy_sign_vars, current_sell_time) result += [(current_sell_time_sum.copy(), partial_buy_sum.copy(), partial_sell_sum.copy())] for left, middle, right in result: model += sum(left) <= inventory + sum(middle) - sum(right) # Measure the time taken to generate the ILP. time_to_generate_ilp = time.time() - t0 # Solve the integer program and hide the output given by the solver. t0_solve = time.time() model.solve(pulp.PULP_CBC_CMD(msg=False)) time_to_solve_ilp = time.time() - t0_solve # Record which contracts should be signed. We start by assuming no contracts will be signed. list_of_signatures = [None] * len(agreements) for agreement in buy_agreements_copy: if buy_sign_vars[agreement[ SCMLContractsSigner. SUB_INDEX]].varValue is not None and int( buy_sign_vars[agreement[ SCMLContractsSigner.SUB_INDEX]].varValue) == 1: list_of_signatures[agreement[ SCMLContractsSigner.MASTER_INDEX]] = agent_id for agreement in sell_agreements_copy: if sell_sign_vars[agreement[ SCMLContractsSigner. SUB_INDEX]].varValue is not None and int( sell_sign_vars[agreement[ SCMLContractsSigner.SUB_INDEX]].varValue) == 1: list_of_signatures[agreement[ SCMLContractsSigner.MASTER_INDEX]] = agent_id # Return multiple objects for inspection purposes. In production, we care about the list of sign contracts, 'list_of_signatures'. return { 'list_of_signatures': list_of_signatures, 'agent_id': agent_id, 'model': model, 'time_to_generate_ilp': time_to_generate_ilp, 'time_to_solve_ilp': time_to_solve_ilp, 'agreements': agreements, 'trust_probabilities': trust_probabilities, 'profit': pulp.value(model.objective) }
# import the library PuLP as p import pulp as p # Set Up a LP Maximization Problem: Lp_prob = p.LpProblem('Activity-Analysis_1', p.LpMaximize) # Here we named the Problem "Acitity-Analysis". # Set Up Problem Variables: c = p.LpVariable("c", lowBound = 0) # "c" for chair t = p.LpVariable("t", lowBound = 0) # "t" for table d = p.LpVariable("d", lowBound = 0) # "d" for desk b = p.LpVariable("b", lowBound = 0) # "b" for bookshelve # Create Objective Function: Lp_prob += 45 * c + 80 * t + 110 * d + 55 * b # Create Constraints: Lp_prob += 5 * c + 20 * t + 15 * d + 22 * b <= 20000 Lp_prob += 10 * c + 15 * t + 25 * d + 20 * b <= 4000 Lp_prob += 3 * c + 8 * t + 15 * d + 10 * b <= 2000 Lp_prob += 4 * c + 20 * d <= 3000 Lp_prob += 20 * b <= 500 # Show the problem: print(Lp_prob) # note that it's shown in alphabetical order ### Simplifying the Problem and Solving it ### # Generate a New LP Maximization Problem:
def solve(professors, courses, semesters, slots): prob = pulp.LpProblem("Semester Problem", pulp.LpMaximize) opt_terms = [] for k, v in lp_vars.items(): if k[2] in n1s + n2s: opt_terms.append(100 * lp_vars_rev[v.name][2].size * v) else: opt_terms.append(lp_vars_rev[v.name][2].size * v) opt_fun = pulp.lpSum(lp_vars_rev[v.name][2].size * v for k, v in lp_vars.items()) prob += opt_fun #print(lp_vars.keys()) # Maximum one class for slot for s in slots: for sem in semesters: v = pulp.lpSum(lp_vars[(p, c, s, sem)] \ for p in professors \ for c in courses) prob += v <= 1 #s.size #for sem in semesters: # for s in sem.slots: # v = pulp.lpSum(lp_vars[(p, c, s, sem)] \ # for p in professors \ # for c in courses) # prob += v <= 1 #s.size for s in slots: for p in professors: v = pulp.lpSum(lp_vars[(p, c, s, sem)] \ for sem in semesters \ for c in courses) prob += v <= 1 #s.size # previne que haja choque entre os professores das turmas conjuntas for s in slots: a = pulp.lpSum(lp_vars[(priscila, c, s, sem)] \ for sem in semesters \ for c in courses) b = pulp.lpSum(lp_vars[(guilherme, c, s, sem)] \ for sem in semesters \ for c in courses) c = pulp.lpSum(lp_vars[(priscila_guilherme, c, s, sem)] \ for sem in semesters \ for c in courses) prob += a + c <= 1 #s.size prob += b + c <= 1 #s.size # previne que haja choque entre os professores das turmas conjuntas for s in slots: a = pulp.lpSum(lp_vars[(padilha, c, s, sem)] \ for sem in semesters \ for c in courses) b = pulp.lpSum(lp_vars[(emilio, c, s, sem)] \ for sem in semesters \ for c in courses) c = pulp.lpSum(lp_vars[(emilio_padilha, c, s, sem)] \ for sem in semesters \ for c in courses) prob += a + c <= 1 #s.size prob += b + c <= 1 #s.size for s in sex_noite: for sem in semesters: v = pulp.lpSum(lp_vars[(priscila_guilherme, c, s, sem)] \ for c in courses) prob += v == 0 #s.size for s in sex_noite: for sem in semesters: v = pulp.lpSum(lp_vars[(guilherme, c, s, sem)] \ for c in courses) prob += v == 0 #s.size for s in sex_noite: for sem in semesters: v = pulp.lpSum(lp_vars[(raquel, c, s, sem)] \ for c in courses) prob += v == 0 #s.size # Each professor must only give his classes for p in professors: v = pulp.lpSum(lp_vars[(p, c, s, sem)] * s.size \ for s in slots \ for c in p.courses \ for sem in semesters ) prob += v <= sum(c.num_hours for c in p.courses) # Each professor must not give other professor's classes for p in professors: v = pulp.lpSum(lp_vars[(p, c, s, sem)] \ for s in slots \ for c in courses if not c in p.courses \ for sem in semesters ) prob += v == 0 # Each course must be complete for c in cs: v = pulp.lpSum(lp_vars[(p, c, s, sem)] * s.size \ for s in slots \ for p in ps \ for sem in semesters ) prob += v <= c.num_hours # Each semester must have all its courses filled #for sem in semesters: # v = pulp.lpSum(lp_vars[(p, c, s, sem)] * s.size \ # for s in sem.slots \ # for p in ps \ # for c in sem.courses) # prob += v <= sum(c.num_hours for c in sem.courses) # Each semester must only have its courses # tested for sem in semesters: v = pulp.lpSum(lp_vars[(p, c, s, sem)] \ for s in slots \ for p in ps \ for c in cs if not c in sem.courses) prob += v == 0 # Each semester must only have its slots # tested for sem in semesters: v = pulp.lpSum(lp_vars[(p, c, s, sem)] \ for s in slots if not s in sem.slots \ for p in ps \ for c in cs) prob += v == 0 # aplica as restrições legais for p in professors: #print(p, proibidos) for (a, b) in proibidos: va = pulp.lpSum(lp_vars[(p, c, a, sem)] \ for c in p.courses \ for sem in semesters ) vb = pulp.lpSum(lp_vars[(p, c, b, sem)] \ for c in p.courses \ for sem in semesters ) prob += va + vb <= 1 # aplica restrições legais a turmas cojuntas for (a, b) in proibidos: va1 = pulp.lpSum(lp_vars[(priscila, c, b, sem)] \ for c in courses \ for sem in semesters ) va2 = pulp.lpSum(lp_vars[(guilherme, c, b, sem)] \ for c in courses \ for sem in semesters ) vb = pulp.lpSum(lp_vars[(priscila_guilherme, c, a, sem)] \ for c in courses \ for sem in semesters ) prob += va1 + vb <= 1 prob += va2 + vb <= 1 va1 = pulp.lpSum(lp_vars[(emilio, c, b, sem)] \ for c in courses \ for sem in semesters ) va2 = pulp.lpSum(lp_vars[(padilha, c, b, sem)] \ for c in courses \ for sem in semesters ) vb = pulp.lpSum(lp_vars[(emilio_padilha, c, a, sem)] \ for c in courses \ for sem in semesters ) prob += va1 + vb <= 1 prob += va2 + vb <= 1 va1 = pulp.lpSum(lp_vars[(priscila, c, a, sem)] \ for c in courses \ for sem in semesters ) va2 = pulp.lpSum(lp_vars[(guilherme, c, a, sem)] \ for c in courses \ for sem in semesters ) vb = pulp.lpSum(lp_vars[(priscila_guilherme, c, b, sem)] \ for c in courses \ for sem in semesters ) prob += va1 + vb <= 1 prob += va2 + vb <= 1 va1 = pulp.lpSum(lp_vars[(emilio, c, a, sem)] \ for c in courses \ for sem in semesters ) va2 = pulp.lpSum(lp_vars[(padilha, c, a, sem)] \ for c in courses \ for sem in semesters ) vb = pulp.lpSum(lp_vars[(emilio_padilha, c, b, sem)] \ for c in courses \ for sem in semesters ) prob += va1 + vb <= 1 prob += va2 + vb <= 1 # previne aulas faixa for p in professors: if not p.faixa: for (a, b) in evitar: va = pulp.lpSum(lp_vars[(p, c, a, sem)] \ for c in p.courses \ for sem in semesters ) vb = pulp.lpSum(lp_vars[(p, c, b, sem)] \ for c in p.courses \ for sem in semesters ) prob += va + vb <= 1 prob.solve() print("Status:", pulp.LpStatus[prob.status]) #for v in prob.variables(): # if v.varValue and v.varValue > 0: # print(v.name, "=", v.varValue) def get_slot(s_, sem_): for (p, c, s, sem), v in lp_vars.items(): if sem_ is sem and s is s_ and pulp.value(v) > 0: #.varValue > 0: return lp_vars_rev[v.name] #print("\n\n\n") def print_m_(ms, sem): linha = [] for s in ms: x = get_slot(s, sem) if x: label = "%s %s" % (x[0].name, x[1].name) else: label = "()" linha.append(label.center(16)) print(",".join(linha)) for sem in semesters: print("\n\n", sem) print("7:30, ", end=' ') print_m_(m1s, sem) print("10:10,", end=' ') print_m_(m2s, sem) print("13:30,", end=' ') print_m_(t1s, sem) print("16:10,", end=' ') print_m_(t2s, sem) print("19:10,", end=' ') print_m_(n1s, sem) print("21:00,", end=' ') print_m_(n2s, sem) print("Total Value:", pulp.value(prob.objective)) print("\nCCR c/ carga horário insuficiente:") for c in cs: v = pulp.lpSum(lp_vars[(p, c, s, sem)] \ for s in slots \ for p in ps \ for sem in semesters) if pulp.value(v) < 2: print("CCR:", c.name, "HS:", pulp.value(v))
def avg_link_utilization(): h12 = 5 h13 = 10 h23 = 7 cap12 = 10 cap13 = 10 cap23 = 15 prob = pulp.LpProblem("3Node_MultiCommodity_AvgDelay", pulp.LpMinimize) # Defining the Flow Variables x12 = pulp.LpVariable('x12', lowBound=0, cat='Continuous') x132 = pulp.LpVariable('x132', lowBound=0, cat='Continuous') x13 = pulp.LpVariable('x13', lowBound=0, cat='Continuous') x123 = pulp.LpVariable('x123', lowBound=0, cat='Continuous') x23 = pulp.LpVariable('x23', lowBound=0, cat='Continuous') x213 = pulp.LpVariable('x213', lowBound=0, cat='Continuous') y12 = pulp.LpVariable('y12', lowBound=0, cat='Continuous') y13 = pulp.LpVariable('y13', lowBound=0, cat='Continuous') y23 = pulp.LpVariable('y23', lowBound=0, cat='Continuous') z12 = pulp.LpVariable('z12', lowBound=0) z13 = pulp.LpVariable('z13', lowBound=0) z23 = pulp.LpVariable('z23', lowBound=0) # Adding Objective Function prob += (z12 * math.pow(cap12, -1) + z13 * math.pow(cap13, -1) + z23 * math.pow(cap23, -1)) # Subject to Constraints prob += (x12 + x132 == h12) prob += (x13 + x123 == h13) prob += (x23 + x213 == h23) prob += (x12 + x123 + x213 == y12) prob += (x13 + x132 + x213 == y13) prob += (x23 + x123 + x123 == y23) prob += (z12 * 2 >= 3 * y12) prob += (z13 * 2 >= 3 * y13) prob += (z23 * 2 >= 3 * y23) prob += (z12 * 2 >= 9 * y12 - 2 * cap12) prob += (z13 * 2 >= 9 * y13 - 2 * cap13) prob += (z23 * 2 >= 9 * y23 - 2 * cap23) prob += (z12 >= 15 * y12 - 8 * cap12) prob += (z13 >= 15 * y13 - 8 * cap13) prob += (z23 >= 15 * y23 - 8 * cap23) prob += (z12 >= 50 * y12 - 36 * cap12) prob += (z13 >= 50 * y13 - 36 * cap13) prob += (z23 >= 50 * y23 - 36 * cap23) prob += (z12 >= 200 * y12 - 171 * cap12) prob += (z13 >= 200 * y13 - 171 * cap13) prob += (z23 >= 200 * y23 - 171 * cap23) prob += (z12 >= 4000 * y12 - 3781 * cap12) prob += (z13 >= 4000 * y13 - 3781 * cap13) prob += (z23 >= 4000 * y23 - 3781 * cap23) # Print the Problem print(prob) prob.writeLP("3node_MCF_AvgDelay.lp") # solve the LP using the CPLEX Solver optimization_result = prob.solve(pulp.CPLEX()) # make sure we got an optimal solution assert optimization_result == pulp.LpStatusOptimal # display the results for var in (x12, x132, x13, x123, x23, x213): print('Optimal Flow for {} is {:1.0f}'.format(var.name, var.value()))