def main(input_path="ubicaciones.csv", balance_deviations=[0.1, 0.15, 0.2, 0.3]): """ Use different balance deviations to test complex lp function to minimize. Args: input_path : csv path with information regarding agencies, frequency, volume and coordinates balance_deviations = list with percentage of deviations, for calaculation refer to stops_gap and items_gap Returns: None """ df = pd.read_csv(input_path) df.loc[df[df["Vol_Entrega"] == 0].index, "Vol_Entrega"] = 1 zones = ["D1", "D2", "D3", "D4", "D5", "D6"] agencies = list("A" + df["Id_Cliente"].astype(str)) vol_delivery = list(df["Vol_Entrega"]) vol_stores = list(df["Vol_Entrega"] * df["Frecuencia"]) frequency = list(df["Frecuencia"]) stores_volume = dict(zip(agencies, vol_stores)) stores_frequency = dict(zip(agencies, frequency)) vol_delivery = dict(zip(agencies, vol_delivery)) scaler = MinMaxScaler() fitted_scaler = scaler.fit(df[["lat", "lon"]]) scaled_coordinates = fitted_scaler.transform(df[["lat", "lon"]]) kmeans = KMeansConstrained(n_clusters=6, size_min=604, size_max=605, random_state=12, n_init=100, max_iter=200, n_jobs=-1) kmeans_values = kmeans.fit(scaled_coordinates) df["kmeans"] = list(kmeans.predict(scaled_coordinates)) vectorized_lat_lon = df[["lat", "lon"]].to_numpy() cluster_centers = fitted_scaler.inverse_transform(kmeans.cluster_centers_) distance_matrix = cdist(cluster_centers, vectorized_lat_lon, metric="cityblock") routes = [(z, a) for z in zones for a in agencies] distances = pulp.makeDict([zones, agencies], distance_matrix, 0) flow = pulp.LpVariable.dicts("Distribution", (zones, agencies), 0, None) using = pulp.LpVariable.dicts("BelongstoZone", (zones, agencies), 0, 1, pulp.LpInteger) for percentage in balance_deviations: prob = pulp.LpProblem("BrewingDataCup2020_" + str(percentage), pulp.LpMinimize) prob += pulp.lpSum([ distances[z][a] * flow[z][a] for (z, a) in routes ]) + pulp.lpSum([distances[z][a] * using[z][a] for (z, a) in routes]), "totalCosts" stops_upper, stops_lower = stops_gap(percentage) distr_upper, distr_lower = items_gap(percentage) for z in zones: prob += pulp.lpSum([using[z][a] for a in agencies ]) <= stops_upper, "SumStopsInZoneUpper %s" % z prob += pulp.lpSum([using[z][a] for a in agencies ]) >= stops_lower, "SumStopsInZoneLower %s" % z prob += pulp.lpSum([flow[z][a] for a in agencies ]) <= distr_upper, "SumDistrInZoneUpper %s" % z prob += pulp.lpSum([flow[z][a] for a in agencies ]) >= distr_lower, "SumDistrInZoneLower %s" % z for z in zones: for a in agencies: prob += flow[z][a] - (100000 * using[z][a]) <= 0 prob += flow[z][a] <= vol_delivery[a] for a in agencies: prob += pulp.lpSum([flow[z][a] for z in zones ]) >= stores_volume[a], "Distribution %s" % a prob += pulp.lpSum([ using[z][a] for z in zones ]) == stores_frequency[a], "FrequencyDistribution %s" % a prob.writeLP("lp_files/milp_brewing_" + str(percentage) + ".lp") solver = pulp.CPLEX_CMD(path=path_to_cplex) prob.solve(solver) print("Estado: ", pulp.LpStatus[prob.status]) print("Total Cost: ", pulp.value(prob.objective)) final_df = pd.DataFrame(columns=["D1", "D2", "D3", "D4", "D5", "D6"], index=(range(1, 3626))) final_distr = dict() for v in prob.variables(): if (v.name).find("BelongstoZone_") == 0: if v.varValue > 0: dist = v.name[14:] zone = dist[:2] id_cliente = int(dist[4:]) final_df.loc[id_cliente, zone] = 1 final_df.fillna(0, inplace=True) final_df = final_df.astype(int).reset_index().rename( columns={"index": "Id_Cliente"}) final_df.to_csv("lp_solutions/cplex_opt_" + str(percentage) + "_" + str(pulp.value(prob.objective)) + ".csv", header=True, index=False)
def solve(self,msg=0,**kwarg): # kind = 'CBC' if 'kind' in kwarg: kind = kwarg['kind'] time_limit = None if 'time_limit' in kwarg: time_limit = float(kwarg['time_limit']) random_seed = None if 'random_seed' in kwarg: random_seed = kwarg['random_seed'] ratio_gap = None if 'ratio_gap' in kwarg: ratio_gap = float(kwarg['ratio_gap']) start_time = time.time() # select solver for pl if kind == 'CPLEX': if time_limit is not None: # pulp does currently not support a timelimit in 1.5.9 self.mip.solve(pl.CPLEX_CMD(msg=msg, timelimit=time_limit)) else: self.mip.solve(pl.CPLEX_CMD(msg=msg)) elif kind == 'GLPK': self.mip.solve(pl.GLPK_CMD(msg=msg)) elif kind == 'SCIP': self.mip.solve(SCIP_CMD(msg=msg,time_limit=time_limit,ratio_gap=ratio_gap)) elif kind == 'CBC' or kind == 'COIN': options = [] if time_limit is not None: options.extend(['sec', str(time_limit)]) if random_seed is not None: options.extend(['randomSeed', str(random_seed)]) options.extend(['randomCbcSeed', str(random_seed)]) if ratio_gap is not None: options.extend(['ratio', str(ratio_gap)]) if kind == 'CBC': self.mip.solve(pl.PULP_CBC_CMD(msg=msg, options=options)) elif kind == 'COIN': self.mip.solve(pl.COIN(msg=msg, options=options)) elif kind == 'GUROBI': # GUROBI_CMD does not support a timelimit or epgap # GUROBI cannot dispatch parameters from options correctly options=[] if time_limit is not None: if ratio_gap is not None: self.mip.solve(pl.GUROBI(msg=msg,timeLimit=time_limit,epgap=ratio_gap)) elif time_limit is not None: self.mip.solve(pl.GUROBI(msg=msg, timeLimit=time_limit)) elif ratio_gap is not None: self.mip.solve(pl.GUROBI(msg=msg, epgap=ratio_gap)) else: self.mip.solve(pl.GUROBI_CMD(msg=msg)) else: raise Exception('ERROR: solver ' + kind + ' not known') if msg: print('INFO: execution time for solving mip (sec) = ' + str(time.time() - start_time)) if self.mip.status == 1 and msg: print('INFO: objective = ' + str(pl.value(self.mip.objective)))
def getCplexSolver(): """ 获取IBM的CPlex :return: """ solver = pl.CPLEX_CMD(keepFiles=True) return solver
def test_bdo(): exchange_mets = { 'C00091': -1, # Succinyl-CoA 'C00004': -4, # NADH 'C00003': 4, # NAD+ 'C00010': 1, # coa 'C00001': 1, # h2O '14bdo': 1, } novel_mets = {'14bdo': 'OCCCCO'} iterations = 50 project = './novoStoic_result' path_to_cplex = '/Users/linuswang/Applications/IBM/ILOG/CPLEX_Studio1261/cplex/bin/x86-64_osx/cplex' pulp_solver = pulp.CPLEX_CMD(path=path_to_cplex, keepFiles=0, mip=1, msg=1) # pulp_solver = pulp.solvers.CPLEX_CMD(path=None,keepFiles=0, mip=1, msg=1) # pulp_solver = pulp.solvers.GUROBI_CMD() # pulp_solver = pulp.solvers.GLPK_CMD() use_direction = True novoStoic_minFlux_relaxedRule(exchange_mets, novel_mets, project, iterations, pulp_solver, use_direction) use_direction = False novoStoic_minFlux_relaxedRule(exchange_mets, novel_mets, project, iterations, pulp_solver, use_direction)
def _solve(self): if self.solver == "cbc": self.prob.solve( pulp.PULP_CBC_CMD( msg=0, maxSeconds=self.time_limit, options=["startalg", "barrier", "crossover", "0"], )) elif self.solver == "cplex": self.prob.solve( pulp.CPLEX_CMD( msg=0, timelimit=self.time_limit, options=["set lpmethod 4", "set barrier crossover -1"], )) elif self.solver == "gurobi": gurobi_options = [ ("Method", 2), # 2 = barrier ("Crossover", 0), ] # Only specify time limit if given (o.w. errors) if self.time_limit is not None: gurobi_options.append(( "TimeLimit", self.time_limit, )) self.prob.solve(pulp.GUROBI(msg=0, options=gurobi_options))
def solve(self, solver_name: str = "cbc", initial_tour: List[int] = None, threads: int = 2) -> List[int]: ws = False if initial_tour: self.warmStart(initial_tour) ws = True if solver_name == "cbc": solver = pulp.PULP_CBC_CMD(msg=0, warmStart=ws, threads=threads) elif solver_name == "cplex": solver = pulp.CPLEX_CMD(msg=0, threads=threads) else: print(f"Cannot use {solver_name} to solve.") print("We use cbc solver instead.") try: status = self.problem.solve(solver) except: solver = pulp.PULP_CBC_CMD(msg=0, warmStart=ws, threads=threads) status = self.problem.solve(solver) tour = list(self.cities) tour.sort(key=lambda x: self.u[x].value()) for i, j in zip(tour, tour[1:] + tour[:1]): assert isclose(self.x[i][j].value(), 1) assert len(tour) == self.ncity return tour
def _solve(self, relax: bool, time_limit: Optional[int]): # Set variable types if not relax: # Set partitioning constraints and artificial variables to integer # (for the periodic case) for node in self.G.nodes(): if (node not in ["Source", "Sink"] and "depot_from" not in self.G.nodes[node] and "depot_to" not in self.G.nodes[node]): for const in self.prob.constraints: # Modify the self.prob object (the # self.set_covering_constrs object cannot be modified # (?)) if "visit_node" in const: self.prob.constraints[ const].sense = pulp.LpConstraintEQ if (self.periodic and self.G.nodes[node]["frequency"] > 1 and node != "Source"): self.dummy[node].cat = pulp.LpInteger # Set route variables to integer for var in self.y.values(): # Disallow routes that visit multiple nodes if "non" in var.name: var.upBound = 0 var.lowBound = 0 var.cat = pulp.LpInteger # Force vehicle bound artificial variable to 0 for var in self.dummy_bound.values(): if "artificial_bound_" in var.name: var.upBound = 0 var.lowBound = 0 # Solve with appropriate solver if self.solver == "cbc": self.prob.solve( pulp.PULP_CBC_CMD( msg=False, timeLimit=time_limit, options=["startalg", "barrier", "crossover", "0"], )) elif self.solver == "cplex": self.prob.solve( pulp.CPLEX_CMD( msg=False, timeLimit=time_limit, # options=["set lpmethod 4", "set barrier crossover -1"], # set barrier crossover -1 is deprecated options=["set lpmethod 4", "set solutiontype 2"], )) elif self.solver == "gurobi": gurobi_options = [ ("Method", 2), # 2 = barrier ("Crossover", 0), ] # Only specify time limit if given (o.w. errors) if time_limit is not None: gurobi_options.append(( "TimeLimit", time_limit, )) self.prob.solve(pulp.GUROBI(msg=False, options=gurobi_options))
def _solve(self, time_limit): if self.solver == "cbc": self.prob.solve(pulp.PULP_CBC_CMD(maxSeconds=time_limit)) elif self.solver == "cplex": self.prob.solve(pulp.CPLEX_CMD(msg=0, timelimit=time_limit)) elif self.solver == "gurobi": gurobi_options = [("TimeLimit", time_limit)] self.prob.solve(pulp.GUROBI_CMD(options=gurobi_options))
def configure_solver_user_guide(): print("Solver list: {}.".format(pulp.listSolvers())) print("Solver list (available): {}.".format(pulp.listSolvers(onlyAvailable=True))) solver = pulp.getSolver("CPLEX_CMD") solver = pulp.getSolver("CPLEX_CMD", timeLimit=10) path_to_cplex = r"C:\Program Files\IBM\ILOG\CPLEX_Studio128\cplex\bin\x64_win64\cplex.exe" solver = pulp.CPLEX_CMD(path=path_to_cplex)
def solve(self, msg=0, **kwarg): kind = 'CBC' if 'kind' in kwarg: kind = kwarg['kind'] time_limit = None if 'time_limit' in kwarg: time_limit = kwarg['time_limit'] random_seed = None if 'random_seed' in kwarg: random_seed = kwarg['random_seed'] ratio_gap = None if 'ratio_gap' in kwarg: ratio_gap = kwarg['ratio_gap'] start_time = time.time() # select solver for pl if kind == 'CPLEX': if time_limit is not None: # pulp does currently not support a timelimit in 1.5.9 self.mip.solve(pl.CPLEX_CMD(msg=msg, timelimit=time_limit)) else: self.mip.solve(pl.CPLEX_CMD(msg=msg)) elif kind == 'GLPK': self.mip.solve(pl.GLPK_CMD(msg=msg)) elif kind == 'CBC': options = [] if time_limit is not None: options.extend(['sec', str(time_limit)]) if random_seed is not None: options.extend(['randomSeed', str(random_seed)]) options.extend(['randomCbcSeed', str(random_seed)]) if ratio_gap is not None: options.extend(['ratio', str(ratio_gap)]) self.mip.solve(pl.PULP_CBC_CMD(msg=msg, options=options)) else: raise Exception('ERROR: solver ' + kind + ' not known') if msg: print('INFO: execution time for solving mip (sec) = ' + str(time.time() - start_time)) if self.mip.status == 1 and msg: print('INFO: objective = ' + str(pl.value(self.mip.objective)))
def _solve(self, time_limit): if self.solver == "cbc": self.prob.solve(pulp.PULP_CBC_CMD(msg=False, timeLimit=time_limit)) elif self.solver == "cplex": self.prob.solve(pulp.CPLEX_CMD(msg=False, timeLimit=time_limit)) elif self.solver == "gurobi": gurobi_options = [] if time_limit is not None: gurobi_options.append(( "TimeLimit", time_limit, )) self.prob.solve(pulp.GUROBI(msg=False, options=gurobi_options))
def optimize(self): """ Default solver is 'cbc' unless solver is set to something else. You may need to provide a path for any of the solvers using 'path' argument. """ if model_params['write_lp']: logger.info('Writing the lp file!') self.model.writeLP(self.model.name + '.lp') logger.info('Optimization starts!') _solver = pulp.PULP_CBC_CMD(keepFiles=model_params['write_log'], fracGap=model_params['mip_gap'], maxSeconds=model_params['time_limit'], msg=model_params['display_log']) if model_params['solver'] == 'gurobi': _solver = pulp.GUROBI(msg=model_params['write_log'], timeLimit=model_params['time_limit'], epgap=model_params['mip_gap']) elif model_params['solver'] == 'cplex': options = [] if model_params['mip_gap']: set_mip_gap = "set mip tolerances mipgap {}".format( model_params['mip_gap']) options.append(set_mip_gap) _solver = pulp.CPLEX_CMD(keepFiles=model_params['write_log'], options=options, timelimit=model_params['time_limit'], msg=model_params['display_log']) elif model_params['solver'] == 'glpk': # Read more about glpk options: https://en.wikibooks.org/wiki/GLPK/Using_GLPSOL options = [] if model_params['mip_gap']: set_mip_gap = "--mipgap {}".format(model_params['mip_gap']) options.append(set_mip_gap) if model_params['time_limit']: set_time_limit = "--tmlim {}".format( model_params['time_limit']) options.append(set_time_limit) _solver = pulp.GLPK_CMD(keepFiles=model_params['write_log'], options=options, msg=model_params['display_log']) self.model.solve(solver=_solver) if self.model.status == pulp.LpStatusOptimal: logger.info('The solution is optimal and the objective value ' 'is ${:,.2f}'.format(pulp.value(self.model.objective)))
def _solve(self, relax: bool, time_limit: Optional[int]): # Set variable types for var in self.prob.variables(): if relax: var.cat = pulp.LpContinuous else: var.cat = pulp.LpInteger # Force vehicle bound artificial variable to 0 if "artificial_bound_" in var.name: var.upBound = 0 var.lowBound = 0 self.prob.writeLP("master.lp") # Solve with appropriate solver if self.solver == "cbc": self.prob.solve( pulp.PULP_CBC_CMD( msg=False, timeLimit=time_limit, options=["startalg", "barrier", "crossover", "0"], )) elif self.solver == "cplex": self.prob.solve( pulp.CPLEX_CMD( msg=False, timeLimit=time_limit, options=["set lpmethod 4", "set barrier crossover -1"], )) elif self.solver == "gurobi": gurobi_options = [ ("Method", 2), # 2 = barrier ("Crossover", 0), ] # Only specify time limit if given (o.w. errors) if time_limit is not None: gurobi_options.append(( "TimeLimit", time_limit, )) self.prob.solve(pulp.GUROBI(msg=False, options=gurobi_options))
def optimize(self): """ Default solver is 'cbc' unless solver is set to something else. You may need to provide a path for any of the solvers using 'path' argument. """ _solver = None s_name = model_params['solver'] w_log = model_params['write_log'] disp_log = model_params['display_log'] mip_gap = model_params['mip_gap'] tl = model_params['time_limit'] if model_params['write_lp']: logger.info('Writing the lp file!') self.model.writeLP(self.model.name + '.lp') if not s_name or s_name == 'cbc': _solver = pulp.PULP_CBC_CMD(keepFiles=w_log, msg=disp_log, gapRel=mip_gap, timeLimit=tl) elif s_name == 'gurobi': # One can use GUROBI_CMD like CPLEX_CMD and pass mip_gap and time_limit as options _solver = pulp.GUROBI(msg=w_log, gapRel=mip_gap, timeLimit=tl) elif s_name == 'cplex': _solver = pulp.CPLEX_CMD(keepFiles=w_log, msg=disp_log, gapRel=mip_gap, timelimit=tl) elif s_name == 'glpk': # Read more about glpk options: https://en.wikibooks.org/wiki/GLPK/Using_GLPSOL options = [] if mip_gap: set_mip_gap = f'--mipgap {mip_gap}' options.append(set_mip_gap) _solver = pulp.GLPK_CMD(keepFiles=w_log, msg=disp_log, options=options, timeLimit=tl) elif s_name == 'xpress': _solver = pulp.XPRESS(keepFiles=w_log, msg=disp_log, gapRel=mip_gap, timeLimit=tl) logger.info('Optimization starts!') self.model.solve(solver=_solver) if self.model.status == pulp.LpStatusOptimal: logger.info(f'The solution is optimal and the objective value ' f'is ${self.model.objective.value():,.2f}')
def test_isovalarate(): exchange_mets = { 'C00141': -1, # 2-keto isovalarate 'C00004': -1, # NADH 'C00003': 1, # NAD+ "C14710": 1, # isobutanol C4H10O 'C00011': 1, # co2 } novel_mets = {} iterations = 50 project = './novoStoic_isovalarate' path_to_cplex = '/Users/linuswang/Applications/IBM/ILOG/CPLEX_Studio1261/cplex/bin/x86-64_osx/cplex' pulp_solver = pulp.CPLEX_CMD(path=path_to_cplex, keepFiles=0, mip=1, msg=1) # pulp_solver = pulp.solvers.CPLEX_CMD(path=None,keepFiles=0, mip=1, msg=1) # pulp_solver = pulp.solvers.GUROBI_CMD() # pulp_solver = pulp.GLPK_CMD() # use_direction=True # novoStoic_minFlux_relaxedRule(exchange_mets, novel_mets,project,iterations,pulp_solver,use_direction) use_direction = False novoStoic_minFlux_relaxedRule(exchange_mets, novel_mets, project, iterations, pulp_solver, use_direction)
cens = cens.loc[some_pop, keep_vars].reset_index(drop=True) # Project data to same as outline epsg_dal = dal_outline.crs.to_epsg() pd = pyproj.Transformer.from_crs(4326, epsg_dal) #4326 is lat/lon cens['x'], cens['y'] = pd.transform(cens.lat, cens.lon) # Create and Solve model # Takes about a minute to create the model fd = fair_distance.fair_dist(cens, ['x', 'y', 'white_pop', 'minor_pop'], grid_dal, ['X', 'Y'], 5, 15 * 5280) #eliminating if over 15 miles away # Takes around 3 minutes to solve fd.solve(pulp.CPLEX_CMD(msg=True)) # Solution is # Total objective value is 37503.64357446054 # White Average Distance 18571.8594672798 # Minority Average Distance 18751.821787230274 # Difference penalty 179.96231995047492 # Make a nice map of the results fd.clust_map(border=dal_outline) #plt.show() # What is the solution if you dont take into account race? md = fair_distance.min_dist(cens, ['x', 'y', 'white_pop', 'minor_pop'], grid_dal, ['X', 'Y'], 5,
print("[Time: %.3f s]" % (end - start)) print("Solving...") Solver(prob) print("Solved.") print("Write Result") dic = {} for ap in air_park: if v_air_park[ap].value() == 1: dic[ap[0]] = ap[1] DicToResult(dic, tb1, filename) score = pulp.value(prob.objective) / problem.p0 + 1 print("Score:", score) if __name__ == "__main__": start = time.clock() tb1, tb2 = getTableS1() #Solver=pulp.GUROBI_CMD().solve Solver = pulp.CPLEX_CMD().solve #Solver=pulp.COIN_CMD(path="F:/Program Files (x86)/COIN-OR/1.7.4/win32-msvc10/bin/cbc.exe").solve #Solver=pulp.GLPK_CMD(path="F:/ToolBox/glpk-4.60/w64/glpsol.exe").solve AirportSolver(Solver, tb1, tb2) end = time.clock() print("Done") print("[Time: %.3f s]" % (end - start))
path_to_cplex = r'C:/Program Files/IBM/ILOG/CPLEX_Studio_Community201/cplex/bin/x64_win64/cplex.exe' import pulp as pl model = pl.LpProblem("Example", pl.LpMinimize) solver = pl.CPLEX_CMD(path=path_to_cplex) _var = pl.LpVariable('a') _var2 = pl.LpVariable('a2') model += _var + _var2 == 1 print("test") result = model.solve(solver) """ facc58cf08ee0-pulp.sol Minimize OBJ: __dummy Subject To _C1: a + a2 = 1 Bounds __dummy = 0 a free a2 free End """ print(result)
Ta=12, In=0.1, Th=10) pmed12.solve(solver=pulp.CPLEX(timeLimit=tl, msg=True)) # takes around 10 minutes #pmed12.solve(solver=pulp.SCIP_CMD(msg=True)) # takes about 5 hours to get the solution #pmed12.solve(solver=pulp.GLPK_CMD(timeLimit=tl,msg=True)) # does not converge even after 12+ hours # Showing a map pmed12.map_plot(carr_report, 'PDGrid') # Figure out subtours stres = pmed12.collect_subtours() # Resolving with warm start with subtour constraints pmed12.solve(solver=pulp.CPLEX_CMD(timeLimit=tl, msg=False, warmStart=True)) # Now it is OK stres = pmed12.collect_subtours() pmed12.map_plot(carr_report, 'PDGrid') ######################################## ## To iterate and resolve if daring #iters = 1 #while (stres == -1) or (iters < 6): # print('Iteration {iters} out of 5') # stres = pmed12.solve(solver=pulp.CPLEX_CMD(msg=False,warmStart=True)) # pmed12.collect_subtours() # iters += 1 #########################################
from pulp import LpProblem, LpMinimize, lpSum, LpInteger, LpVariable, LpStatus, value, CPLEX_CMD import pulp as plp # don't forget to download gurobi with academic license import numpy as np import pandas as pd from matplotlib import pyplot import warnings import math as mth import xlwt from xlwt import Workbook import os.path import sys from matplotlib import cm from matplotlib.ticker import LinearLocator, FormatStrFormatter import docplex.mp.model as cpx solver = plp.CPLEX_CMD( path= r'C:\Program Files\IBM\ILOG\CPLEX_Studio_Community201\cplex\bin\x64_win64\cplex.exe' ) # from mpl_toolkits.basemap import basemap # Class definition class DroneScanningOpt: def __init__(self, area_shape, amount_of_drones_used, location_charging_points, minimum_charge, name, logging_obj, scanning_time,
def solve_centralized(player_list, buying_price, selling_price, batinfo, pvinfo, prob, batfix=None, pvfix=None, proportions_core=None, integer=False): model = plp.LpProblem(name="model") if CPLEX_PATH is not None: solver = plp.CPLEX_CMD(path=CPLEX_PATH, msg=False) else: solver = plp.PULP_CBC_CMD(msg=False) contributions = {} N = len(player_list) set_N = range(N) set_T = range(player_list[0]._x.shape[1]) set_W = range(player_list[0]._x.shape[0]) ## z^+_t zp_vars = {(w, t): plp.LpVariable(cat=plp.LpContinuous, lowBound=0, upBound=None, name="zpXX{0}_{1}".format(w, t)) for t in set_T for w in set_W} ## z^-_t zn_vars = {(w, t): plp.LpVariable(cat=plp.LpContinuous, lowBound=0, upBound=None, name="znXX{0}_{1}".format(w, t)) for t in set_T for w in set_W} ## c^n_t ch_vars = {(w, n, t): plp.LpVariable(cat=plp.LpContinuous, lowBound=0, name="chXX{0}_{1}_{2}".format(w, n, t)) for t in set_T for n in set_N for w in set_W} shared_ch_vars = {(w, t): plp.LpVariable(cat=plp.LpContinuous, lowBound=0, name="schXX{0}_{1}".format(w, t)) for t in set_T for w in set_W} ## d^n_t dis_vars = {(w, n, t): plp.LpVariable(cat=plp.LpContinuous, lowBound=0, name="disXX{0}_{1}_{2}".format(w, n, t)) for t in set_T for n in set_N for w in set_W} shared_dis_vars = {(w, t): plp.LpVariable(cat=plp.LpContinuous, lowBound=0, name="sdisXX{0}_{1}".format(w, t)) for t in set_T for w in set_W} if integer is False: batsize = plp.LpVariable(cat=plp.LpContinuous, lowBound=0, name="batsizeXX") pvsize = plp.LpVariable(cat=plp.LpContinuous, lowBound=0, name="pvsizeXX") else: batsize = plp.LpVariable(cat='Integer', lowBound=0, name="batsizeXX") pvsize = plp.LpVariable(cat='Integer', lowBound=0, name="pvsizeXX") var = [ zp_vars, zn_vars, ch_vars, dis_vars, shared_ch_vars, shared_dis_vars, batsize, pvsize ] vars_ = {} for vi in var: if isinstance(vi, dict): for v in vi.values(): vars_[v.name] = v else: vars_[vi.name] = vi #### Constraints ## Variable boudns ######## Start private batteries ## Private Battery upper bound cons_bat_ub = { (w, n, j): plp.LpConstraint(e=plp.lpSum(ch_vars[(w, n, t)] - dis_vars[(w, n, t)] for t in range(j + 1)), sense=plp.LpConstraintLE, rhs=player_list[n]._sm - player_list[n]._s0, name="cons_bat_up_{0}_{1}_{2}".format(w, n, j)) for j in set_T for n in set_N for w in set_W } for n in set_N: for j in set_T: for w in set_W: cont = np.zeros(N) cont[n] = player_list[n]._sm - player_list[n]._s0 contributions[cons_bat_ub[(w, n, j)].name] = cont for k in cons_bat_ub: model.addConstraint(cons_bat_ub[k]) ## Private Battery lower bound cons_bat_lb = { (w, n, j): plp.LpConstraint(e=-plp.lpSum(ch_vars[(w, n, t)] - dis_vars[(w, n, t)] for t in range(j + 1)), sense=plp.LpConstraintLE, rhs=player_list[n]._s0, name="cons_bat_low_{0}_{1}_{2}".format(w, n, j)) for j in set_T for n in set_N for w in set_W } for k in cons_bat_lb: model.addConstraint(cons_bat_lb[k]) ### Contributions for n in set_N: for j in set_T: for w in set_W: cont = np.zeros(N) cont[n] = player_list[n]._s0 contributions[cons_bat_lb[(w, n, j)].name] = cont ## Private Battery ramp up cons_bnd_ub = { (w, n, t): plp.LpConstraint(e=ch_vars[(w, n, t)], sense=plp.LpConstraintLE, rhs=player_list[n]._ram, name="cons_bnd_up_{0}_{1}_{2}".format(w, n, t)) for t in set_T for n in set_N for w in set_W } for k in cons_bnd_ub: model.addConstraint(cons_bnd_ub[k]) ### Contributions for n in set_N: for j in set_T: for w in set_W: cont = np.zeros(N) cont[n] = player_list[n]._ram contributions[cons_bnd_ub[(w, n, j)].name] = cont ## Private Battery lower bound cons_bnd_lb = { (w, n, t): plp.LpConstraint(e=dis_vars[(w, n, t)], sense=plp.LpConstraintLE, rhs=player_list[n]._ram, name="cons_bnd_low_{0}_{1}_{2}".format(w, n, t)) for t in set_T for n in set_N for w in set_W } for k in cons_bnd_lb: model.addConstraint(cons_bnd_lb[k]) ### Contributions for n in set_N: for j in set_T: for w in set_W: cont = np.zeros(N) cont[n] = player_list[n]._ram contributions[cons_bnd_lb[(w, n, j)].name] = cont ####### End private batteries ####### Start public battery ## Public battery upper bound cons_shared_bat_ub = {(w, j): plp.LpConstraint( e=plp.lpSum(shared_ch_vars[(w, t)] - shared_dis_vars[(w, t)] for t in range(j + 1)) - batinfo['size'] * batsize, sense=plp.LpConstraintLE, rhs=-batinfo['init'], name="cons_shared_bat_up_{0}_{1}".format(w, j)) for j in set_T for w in set_W} for j in set_T: for w in set_W: cont = np.zeros(N) contributions[cons_shared_bat_ub[(w, j)].name] = cont for k in cons_shared_bat_ub: model.addConstraint(cons_shared_bat_ub[k]) ## Private Battery lower bound cons_shared_bat_lb = {(w, j): plp.LpConstraint( e=-plp.lpSum(shared_ch_vars[(w, t)] - shared_dis_vars[(w, t)] for t in range(j + 1)), sense=plp.LpConstraintLE, rhs=batinfo['init'], name="cons_shared_bat_low_{0}_{1}".format(w, j)) for j in set_T for w in set_W} for k in cons_shared_bat_lb: model.addConstraint(cons_shared_bat_lb[k]) ### Contributions for j in set_T: for w in set_W: cont = np.zeros(N) contributions[cons_shared_bat_lb[(w, j)].name] = cont ## Public Battery ramp up cons_shared_bnd_ub = { (w, t): plp.LpConstraint(e=shared_ch_vars[(w, t)] - batinfo['ram'] * batsize, sense=plp.LpConstraintLE, rhs=0, name="cons_shared_bnd_up_{0}_{1}".format(w, t)) for t in set_T for w in set_W } for k in cons_shared_bnd_ub: model.addConstraint(cons_shared_bnd_ub[k]) ### Contributions for j in set_T: for w in set_W: cont = np.zeros(N) contributions[cons_shared_bnd_ub[(w, j)].name] = cont ## Public Battery lower bound cons_shared_bnd_lb = { (w, t): plp.LpConstraint(e=shared_dis_vars[(w, t)] - batinfo['ram'] * batsize, sense=plp.LpConstraintLE, rhs=0, name="cons_shared_bnd_low_{0}_{1}".format(w, t)) for t in set_T for w in set_W } for k in cons_shared_bnd_lb: model.addConstraint(cons_shared_bnd_lb[k]) ### Contributions for j in set_T: for w in set_W: cont = np.zeros(N) contributions[cons_shared_bnd_lb[(w, j)].name] = cont ####### End public batteries ####### Begin fix pv and battery ## Fixing battery if batfix is not None: cons_fix_bat = plp.LpConstraint(e=batsize, sense=plp.LpConstraintEQ, rhs=batfix, name="batfix") model.addConstraint(cons_fix_bat) ### Contributions if proportions_core is None: print('contrib core none') cont = np.ones(N) / N * batfix elif np.allclose(proportions_core, 0): print('contrib core 0') cont = np.zeros(N) else: print('proper contrib') cont = proportions_core / proportions_core.sum() * batfix contributions[cons_fix_bat.name] = cont ## Fixing PV if pvfix is not None: cons_fix_pv = plp.LpConstraint(e=pvsize, sense=plp.LpConstraintEQ, rhs=pvfix, name="pvfix") model.addConstraint(cons_fix_pv) ### Contributions if proportions_core is None: cont = np.ones(N) / N * pvfix elif np.allclose(proportions_core, 0): cont = np.zeros(N) else: cont = proportions_core / proportions_core.sum() * pvfix contributions[cons_fix_pv.name] = cont # if proportions_core is not None: # cont = proportions_core / proportions_core.sum() * pvfix # else: # cont = np.ones(N) / N * pvfix # contributions[cons_fix_pv.name] = cont ####### ####### Net energy equations ### On side of the equality SEC = 1 / batinfo['ec'] SED = batinfo['ed'] cons_z = {(w, t): plp.LpConstraint( e=plp.lpSum(zp_vars[(w, t)] - zn_vars[(w, t)] - plp.lpSum( ch_vars[(w, n, t)] * (1 / player_list[n]._ec) - dis_vars[(w, n, t)] * player_list[n]._ed for n in set_N) - (shared_ch_vars[(w, t)] * SEC - shared_dis_vars[(w, t)] * SED) - pvsize * pvinfo['data'][(w, t)]), sense=plp.LpConstraintLE, rhs=sum(player_list[n]._x[w, t] for n in set_N), name="cons_z_{0}_{1}".format(w, t)) for t in set_T for w in set_W} for k in cons_z: model.addConstraint(cons_z[k]) ### Contributions for w in set_W: for j in set_T: cont = np.zeros(N) for n2 in set_N: cont[n2] = player_list[n2]._x[w, j] contributions[cons_z[(w, j)].name] = cont #### The other side cons_zo = {(w, t): plp.LpConstraint( e=-plp.lpSum(zp_vars[(w, t)] - zn_vars[(w, t)] - plp.lpSum( ch_vars[(w, n, t)] * (1 / player_list[n]._ec) - dis_vars[(w, n, t)] * player_list[n]._ed for n in set_N) - (shared_ch_vars[(w, t)] * SEC - shared_dis_vars[ (w, t)] * SED) - pvsize * pvinfo['data'][(w, t)]), sense=plp.LpConstraintLE, rhs=-sum(player_list[n]._x[w, t] for n in set_N), name="cons_zo_{0}_{1}".format(w, t)) for t in set_T for w in set_W} for k in cons_zo: model.addConstraint(cons_zo[k]) for w in set_W: for j in set_T: cont = np.zeros(N) for n2 in set_N: cont[n2] = -player_list[n2]._x[w, j] contributions[cons_zo[(w, j)].name] = cont cons = [ cons_bat_ub, cons_bat_lb, cons_bnd_ub, cons_bnd_lb, cons_shared_bat_ub, cons_shared_bat_lb, cons_shared_bnd_ub, cons_shared_bnd_lb, cons_z, cons_zo ] objective = plp.lpSum(-batinfo['cost'] * batsize - pvinfo['cost'] * pvsize + plp.lpSum( -zp_vars[(w, t)] * buying_price[t] * prob[w] + zn_vars[(w, t)] * selling_price[t] * prob[w] for t in set_T for w in set_W)) model.sense = plp.LpMaximize model.setObjective(objective) model.solve(solver) opt_val = objective.value() # df = pd.DataFrame(ch_vars.keys()) # df['ch'] = df.apply(lambda x: ch_vars[(x[0], x[1])].varValue, axis=1) # df['dis'] = df.apply(lambda x: dis_vars[(x[0], x[1])].varValue, axis=1) # df.columns = ['n', 't', 'ch', 'dis'] # df_cd = pd.pivot_table(df, index='n', columns='t', values=['ch', 'dis']).round(4) # df = pd.DataFrame(zp_vars.keys()) # df['zp'] = df.apply(lambda x: zp_vars[x[0]].varValue, axis=1) # df['zn'] = df.apply(lambda x: zn_vars[x[0]].varValue, axis=1) # df.columns = ['t', 'zp', 'zn'] # df_z = df.copy() return model, vars_, cons, contributions
Parcel += c[(i, j, k, l)] >= md[(l, j)] - 26 * (1 - y[(i, j, k, l)]) Parcel += c[(i, j, k, l)] >= 0 #With these: c[(i,j,k,l)] = y[(i,j,k,l)]*md[(l,j)] for i in cities: for j in cities: Parcel += mc[(i, j)] >= (e[(i, j)] * o[i]) / 100 Parcel += mc[(i, j)] <= (e[(i, j)] * o[i] + 99) / 100 #mc[(i,j)] is the integer value just above the flow between i and j divided by 100 Parcel += md[(i, j)] >= (e[(j, i)] * d[j]) / 100 Parcel += md[(i, j)] <= (e[(j, i)] * d[j] + 99) / 100 #md[(i,j)] is the integer value just above the flow between i and j divided by 100 for k in cities: for l in cities: Parcel += mt[(k, l)] >= (p.lpSum(y[(i, j, k, l)] * flow[(i, j)] for i in cities for j in cities)) / 100 Parcel += mt[(k, l)] <= (p.lpSum(y[(i, j, k, l)] * flow[(i, j)] for i in cities for j in cities) + 99) / 100 #mt[(k,l)] is the integer value just above the flow between k and l divided by 100 Parcel += p.lpSum(e[(k, k)] for k in cities) >= 1 #There must be at least one hub solver = p.CPLEX_CMD() res = Parcel.solve(solver) print("status:", res) print("OPT:", p.value(Parcel.objective))
def SolveWithReluxation(self, game_type, league='ps', timeLimit=None, solverName=None, threads=1, option=[], initialPosition=None, initialSolution=False): """ This is a function to solve 0-1 integer problem which aim to compute suchedule with minimized distance. Parameters ---------- game_type : str The type of played game. Regular Game before inter game : 'r_pre' Regular Game after inter game : 'r_post' Inter league : 'i' league : str League name Pacific league : 'p' Central league : 's' timeLimit : int Time limit for solver in seconds. solverName : int Solver's name you use 0 : CBC 1 : CPLEX threads : int Threads for solver(default : 1) options : list Options for solver (default : []) initialPosition : list Initial position of every team (default : None) initialSolution : bool If true, start with initial value Returns ------- status : int Status of solved problem 1 : Optimal 0 : Not solved -1 : Infeasible -2 : Unbounded -3 : Undefined objective : int Objective value of solved problem v : list Solution of this problem. """ # 定数 if game_type == 'i': I = self.K else: I = self.Teams[league] S = self.S[game_type] D = self.D total_game = self.total_game[game_type] # 問題の宣言 problem = pulp.LpProblem('scheduling', pulp.LpMinimize) # 変数の生成 v = pulp.LpVariable.dicts('v', (S, I, I), 0, 1, 'Integer') e = pulp.LpVariable.dicts('e', (S, I, I, I), 0, 1, 'Integer') penal1 = pulp.LpVariable.dicts('p1', (I, I), lowBound=0) penal2 = pulp.LpVariable.dicts('p2', (S, I), lowBound=0) penal3 = pulp.LpVariable.dicts('p2', (S, I, I), lowBound=0) # 目的関数の設定 obj = pulp.lpSum([ D[j][k] * e[s][i][j][k] for i in I for j in I for k in I for s in S ]) obj += 100 * ( pulp.lpSum([penal1[i][j] for i in I for j in I]) + pulp.lpSum([penal2[s][i] for s in S for i in I]) + pulp.lpSum([penal3[s][i][j] for s in S for i in I for j in I])) if initialPosition: for i in I: obj += pulp.lpSum( [D[initialPosition[i]][j] * v[0][i][j] for j in I]) problem += obj # 制約式を入れる """制約4,6,8を緩和させる """ for i in I: for j in I: for k in I: for s in S[1:]: # e[s][i][j][k]が定義を満たすように制約を入れる problem += 1 - v[ s - 1][i][j] - v[s][i][k] + e[s][i][j][k] >= 0 problem += v[s - 1][i][j] - e[s][i][j][k] >= 0 problem += v[s][i][k] - e[s][i][j][k] >= 0 for s in S: for i in I: # 垂直に足して見てね!パワポの制約⑦ problem += pulp.lpSum([v[s][j][i] for j in I]) <= 2 for i in I: J = list(set(I) - {i}) for s in S: # v[s][i][i]の決め方。パワポで言う制約① problem += v[s][i][i] - pulp.lpSum([v[s][j][i] for j in J]) == 0 for i in I: J = list(set(I) - {i}) # 総試合数に関する制約。パワポで言う制約② problem += pulp.lpSum([v[s][i][j] for j in I for s in S]) == total_game # ホームゲームとビジターゲームの試合数を揃える。パワポで言う制約③ problem += (pulp.lpSum([v[s][i][j] for s in S for j in J]) - pulp.lpSum([v[s][i][i] for s in S]) == 0) for s in S: for i in I: # 1日必ず1試合する。パワポで言う制約⑤ problem += pulp.lpSum([v[s][i][j] for j in I]) == 1 for i in I: for j in I: # 各対戦カードにおけるホームとビジターの試合数をなるべく揃える。パワポで言う制約④ if i != j: problem += pulp.lpSum( [v[s][i][j] for s in S]) - pulp.lpSum( [v[s][j][i] for s in S]) + penal1[i][j] + penal1[j][i] <= 1 problem += pulp.lpSum( [v[s][i][j] for s in S]) - pulp.lpSum( [v[s][j][i] for s in S]) + penal1[i][j] + penal1[j][i] >= -1 problem += pulp.lpSum( [v[s][i][j] for s in S]) + penal1[i][j] <= self.ub[game_type] problem += pulp.lpSum( [v[s][i][j] for s in S]) + penal1[i][j] >= self.lb[game_type] for s in S[:-2]: for i in I: for j in I: # 連戦はしない。パワポで言う制約⑥ if i != j: problem += pulp.lpSum( [v[t][i][j] + v[t][j][i] for t in range(s, s + 3)]) + penal3[s][i][j] <= 1 for s in S[:-2]: for i in I: # ホームは連続二連ちゃんまで!パワポの制約⑧ problem += pulp.lpSum([v[t][i][i] for t in range(s, s + 3) ]) + penal2[s][i] <= 2 if game_type == 'i': L = self.Teams['p'] J = self.Teams['s'] for s in S: for i in L: # 自分のリーグに属するチームとは試合を行わないと言う制約。パワポの制約⑨ for j in L: if i != j: problem += v[s][i][j] == 0 # もう一方のリーグのチームと一回ずつ試合をするという制約。パワポの制約11 for j in J: problem += v[s][i][j] <= ( 1 - pulp.lpSum([v[t][j][i] for t in range(s)])) for i in J: # 自分のリーグに属するチームとは試合を行わないと言う制約。パワポの制約⑨ for j in J: if i != j: problem += v[s][i][j] == 0 # もう一方のリーグのチームと一回ずつ試合をするという制約。パワポの制約11 for j in L: problem += v[s][i][j] <= ( 1 - pulp.lpSum([v[t][j][i] for t in range(s)])) # ビジターで試合をしている時はホームで試合をしてはいけない。パワポの制約⑩ # v[s][i][i]=1かv[s][i][j]=1の何か一方が成立する for s in S: for i in L: problem += v[s][i][i] + pulp.lpSum([v[s][i][j] for j in J]) <= 1 for j in J: problem += v[s][j][j] + pulp.lpSum([v[s][j][i] for i in L]) <= 1 if initialSolution: v_initial = utils.Load(game_type + "_" + league + '.pkl') for s in S: for i in I: for j in I: v[s][i][j].setInitialValue(v_initial[s][i][j].value()) # solverの設定 # デフォルトは cbc solver if solverName == 0: solver = pulp.PULP_CBC_CMD(msg=1, threads=threads, options=option, maxSeconds=timeLimit, warmStart=True) elif solverName == 1: solver = pulp.CPLEX_CMD(msg=1, timeLimit=timeLimit, options=option, threads=threads, warmStart=True) status = problem.solve(solver) return status, pulp.value(problem.objective), v
def set_packing(vertex_activation_all, importance_weights, similarity_matrix, symmetry_pairs, displacements, blendshape_uniquenesses, triangle_similarities): ## SET PACKING # maximize the total number of subsets # subject to selected sets have to be pairwise disjoint # every set is either in the set packing or not w_vars = [] var_num = 0 for bs in vertex_activation_all: w_vars.append( pulp.LpVariable('w' + str(var_num).zfill(3), lowBound=0, upBound=1, cat='Integer')) var_num += 1 # print("initial_importance_weights: " + str(importance_weights)) current_importance_weights = importance_weights.copy() current_blendshape_uniquenesses = blendshape_uniquenesses.copy() all_results = [] all_indices = list(range(len(vertex_activation_all))) all_pairs = symmetry_pairs.copy() do_symmetry = True one_loop = True while len(all_indices) != 0: oneLoopStartTime = datetime.now() my_lp_problem = pulp.LpProblem("My LP Problem", pulp.LpMaximize) if len(importance_weights) == 0: my_lp_problem += pulp.lpSum(w_vars) else: my_lp_problem += pulp.lpSum( np.array(current_importance_weights) * w_vars) # constraintsStartTime = datetime.now() for i in range(len(vertex_activation_all[0])): vertex_sum = 0 for j in all_indices: vertex_sum += w_vars[j] * vertex_activation_all[j][i] my_lp_problem += pulp.lpSum(vertex_sum) <= 1 # constraintsEndTime = datetime.now() # print("add constraints time: " + str(constraintsEndTime - constraintsStartTime)) # eventually symmetry will cause empty result sets, so in that case no longer take symmetry into account if do_symmetry: # print("remaining blendshapes: " + str(all_indices)) # print("pairs: " + str(all_pairs)) for pair in all_pairs: my_lp_problem += w_vars[pair[0]] - w_vars[pair[1]] == 0 # print(my_lp_problem) my_lp_problem.solve( pulp.CPLEX_CMD(msg=1, options=['set emphasis mip 4'])) oneLoopEndTime = datetime.now() if one_loop: end_one_iter_solve_time = datetime.now() one_loop_time = end_one_iter_solve_time - oneLoopStartTime print("One loop execution time: " + str(one_loop_time)) one_loop = False # print("solved status: " + str(pulp.LpStatus[my_lp_problem.status])) # for variable in my_lp_problem.variables(): # if variable.varValue == 1: # print("{} = {}".format(variable.name, variable.varValue)) result_sum = 0 result_blendshapes = [] for w in my_lp_problem.variables(): if w.varValue == 1: i = int(w.name[1:]) w_vars[i] = 0 # print("removing " + str(i)) result_blendshapes.append(i) all_indices.remove(i) for pair in all_pairs: if i in pair: all_pairs.remove(pair) result_sum += sum(vertex_activation_all[i]) # result_blendshapes_to_print = ep_utils.fix_indices_for_zero_blendshapes(result_blendshapes) result_blendshapes_to_print = result_blendshapes print(result_blendshapes_to_print) # print(result_blendshapes) if len(result_blendshapes) == 0: print("remaining blendshapes: ", ep_utils.get_blendshapes_to_print(all_indices)) print("remaining pairs", [ep_utils.get_blendshapes_to_print(i) for i in all_pairs]) do_symmetry = False else: all_results.append(result_blendshapes) # print(result_sum) # COMMENTING OUT BLENDSHAPE UNIQUENESS FOR THE MOMENT # current_blendshape_uniquenesses = update_blendshape_uniqueness_weights(current_blendshape_uniquenesses, result_blendshapes, similarity_matrix) # current_importance_weights = displacements + current_blendshape_uniquenesses + triangle_similarities # print(pulp.value(my_lp_problem.objective)) print("First loop time: ", one_loop_time) return all_results