def team_divider(member_list, rate_list, number_of_teams): rate_list_copy = [[i] for i in rate_list] rate_list_copy = np.array(rate_list_copy) number_of_members = len(member_list) m = pulp.LpProblem() # 数理モデル x = np.array(addbinvars(number_of_members, number_of_teams)) # 割当 y = np.array(addvars(number_of_teams, 2)) # チーム内の最小と最大 z = addvars(2) # チーム間の最小と最大 m += pulp.lpSum(y[:, 1] - y[:, 0]) + 1.5 * (z[1] - z[0]) # 目的関数 for i in range(number_of_members): m += pulp.lpSum(x[i]) == 1 # どこかのチームに所属 for j in range(number_of_teams): m += pulp.lpDot(rate_list_copy.sum(1), x[:, j]) >= z[0] m += pulp.lpDot(rate_list_copy.sum(1), x[:, j]) <= z[1] for k in range(rate_list_copy.shape[1]): m += pulp.lpDot(rate_list_copy[:, k], x[:, j]) >= y[j, 0] m += pulp.lpDot(rate_list_copy[:, k], x[:, j]) <= y[j, 1] m.solve() # 求解 divide_result = np.vectorize(pulp.value)(x) teamdivide = [ i for i in (divide_result @ range(number_of_teams)).astype(int) ] return teamdivide
def lp(cs, C, ls, ps): """ Args: cs: a list containing the cost of probing `X_1, ..., X_n` C: the cost budget ls: a list of the lengths of the intervals `I_1, ..., I_m`. Each element of the list contains the length of the corresponding interval. ps: a list of functions, each of which takes that take in one argument `j` and returns `Pr[X_i >= a_j]` Returns: a triple of type `(pulp.LpVariable, list of pulp.LpVariable, pulp.LpProblem)` with values of `(z, list of y_i, unsolved linear program)`. """ assert len(ps) == len(cs) n = len(ps) m = len(ls) problem = pulp.LpProblem('Step 1', pulp.LpMinimize) z = pulp.LpVariable('z', cat='Integer') ys = [pulp.LpVariable('y' + str(i), lowBound=0, upBound=1, cat='Integer') for i in xrange(n)] problem += z for j in xrange(1, m + 1): aa = (math.log(1.0 / p(j)) for p in ps) problem += pulp.lpDot(ys, aa) <= math.log(ls[j - 1]) - z, 'j=' + str(j) problem += pulp.lpDot(cs, ys) <= C, 'cost' return z, ys, problem
def get_optimal_allocations(domain, criterion, batch_size, method): candidates = get_candidates(domain, criterion, method, limit=1000) n = len(candidates) ilp_vars = [pulp.LpVariable('x%s' % x, 0, batch_size, pulp.LpInteger) \ for x in range(n)] prices = [candidates[i]['price'] for i in range(n)] confs = [candidates[i]['conf'] for i in range(n)] dists = [candidates[i]['dist'] for i in range(n)] histo = get_availability_histo(domain) ilp = None if method == 'min_price': ilp = pulp.LpProblem('minprice', pulp.LpMinimize) ilp += pulp.lpDot(prices, ilp_vars) ilp += pulp.lpDot(confs, ilp_vars) >= decimal.Decimal(batch_size * criterion) elif method == 'max_conf': ilp = pulp.LpProblem('maxconf', pulp.LpMaximize) ilp += pulp.lpDot(confs, ilp_vars) ilp += pulp.lpDot(prices, ilp_vars) <= decimal.Decimal(criterion) ilp += pulp.lpSum(ilp_vars) == batch_size for level in histo: ilp += pulp.lpDot([dists[i][level - 1] for i in range(n)], \ ilp_vars) <= histo[level] status = ilp.solve(pulp.GLPK(msg=0)) allocs = [] if pulp.LpStatus[status] == 'Optimal': for i in range(n): x = ilp_vars[i] if pulp.value(x) > 0: allocs.append((pulp.value(x), candidates[i])) return allocs
def __calcFirstW(self, goal=1, eps=0.00): oidx = [i for i in range(self.M)] Nsols = len(self.solutionsList) assert self.M == Nsols, 'only fist W' # 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, upBound=1, cat='Continuous').values()) # w = list(prob.add_var()) uR = self.__globalL v = lp.LpVariable('v', cat='Continuous') # v = prob.add_var(name='v', var_type=mip.CONTINUOUS) for conN, sols in enumerate(self.solutionsList): d, dvec = self.__calcD(sols) expr = v - lp.lpDot(w, self.__normf(sols.objs)) # expr = v-mip.xsum(w[i]*self.__normf(sols.objs)[i] for i in range()) prob += expr <= 0 #manter for i in oidx: prob += w[i] >= 0 #manter prob += lp.lpSum([w[i] for i in oidx]) == 1 # prob += mip.xsum([w[i] for i in oidx]) == 1 prob += v - lp.lpDot(w, self.__normf(uR)) # prob += v-mip.xsum(w*self.__normf(uR)[i] for i in range()) try: grbs = lp.GUROBI(msg=False, OutputFlag=False) prob.solve(grbs) except: prob.solve() # status = prob.optimize() feasible = False if prob.status in [-1, -2] else True # feasible = status == OptimizationStatus.OPTIMAL or status == OptimizationStatus.FEASIBLE if feasible: w_ = np.array( [lp.value(w[i]) if lp.value(w[i]) >= 0 else 0 for i in oidx]) # w_ = np.array([w[i].x if w[i].x >= 0 else 0 for i in oidx]) if self.__norm: w_ = w_ / (self.__globalU - self.__globalL) fobj = lp.value(prob.objective) # fobj = prob.objective_values[0] self.__w = np.array(w_) self.__importance = fobj else: raise ('Somethig wrong')
def __calcImportance(self, solutionsList): '''Calculates the importance of a weight using Equation 2 to find the lower point and Proposition 4 of the referenced work to calculate the importance. ''' oidx = [i for i in range(self.M)] prob = lp.LpProblem("Lower point", lp.LpMinimize) uR = list(lp.LpVariable.dicts('uR', oidx, cat='Continuous').values()) for value, sols in enumerate(solutionsList): expr = lp.lpDot(self.__normw(sols.w), uR) cons = self.__normf(sols.objs) @ self.__normw(sols.w) prob += expr >= cons prob += lp.lpDot(self.__normw(self.w), uR) grbs = lp.solvers.GUROBI(msg=False, OutputFlag=False, Threads=1) if grbs.available(): prob.solve(grbs) else: cbcs = lp.solvers.PULP_CBC_CMD(threads=1) prob.solve(cbcs, use_mps=False) feasible = False if prob.status in [-1, -2] else True self.__uR = np.array([lp.value(uR[i]) for i in oidx]) if feasible: self.__importance = ((self.__normw(self.w) @ self.__point - self.__normw(self.w) @ self.__uR) / (self.__normw(sols.w) @ np.ones(self.M))) else: raise ('Non-feasible solution')
def gap(cst, req, cap): """ 一般化割当問題 費用最小の割当を解く 入力 cst: エージェントごと、ジョブごとの費用のテーブル req: エージェントごと、ジョブごとの要求量のテーブル cap: エージェントの容量のリスト 出力 ジョブごとのエージェント番号リスト """ na, nj = len(cst), len(cst[0]) m = LpProblem() v = [[addvar(cat=LpBinary) for _ in range(nj)] for _ in range(na)] m += lpSum(lpDot(cst[i], v[i]) for i in range(na)) for i in range(na): m += lpDot(req[i], v[i]) <= cap[i] for j in range(nj): m += lpSum(v[i][j] for i in range(na)) == 1 if m.solve() != 1: return None return [ int(value(lpDot(range(na), [v[i][j] for i in range(na)]))) for j in range(nj) ]
def assignment_problem(efficiency_matrix): row = len(efficiency_matrix) col = len(efficiency_matrix[0]) flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x] m = pulp.LpProblem('assignment', sense=pulp.LpMinimize) var_x = [[ pulp.LpVariable(f'x{i}{j}', cat=pulp.LpBinary) for j in range(col) ] for i in range(row)] m += pulp.lpDot(efficiency_matrix.flatten(), flatten(var_x)) for i in range(row): m += (pulp.lpDot(var_x[i], [1] * col) == 1) for j in range(col): m += (pulp.lpDot([var_x[i][j] for i in range(row)], [1] * row) == 1) m.solve() print(m) return { 'objective': pulp.value(m.objective), 'var': [[pulp.value(var_x[i][j]) for j in range(col)] for i in range(row)] }
def solve_jiang_guan_lp(return_samples, targets, asset_partition): n = return_samples.shape[1] prob = pulp.LpProblem('Jiang Guan DCCP Sample Approximation', pulp.LpMinimize) x = [pulp.LpVariable('Asset {0:d} Weight'.format(i), 0.0, 1.0) for i in range(n)] mu = calc_first_moment(return_samples) prob += pulp.lpDot(mu, x), 'Sample Mean Return' i = 0 for sample in return_samples: prob += (pulp.lpDot(sample, x) >= targets[0], 'Global return target for sample {0:d}'.format(i)) i += 1 i = 0 j = 1 for assets in asset_partition: for sample in return_samples: prob += (pulp.lpSum([sample[k] * x[k] for k in range(n)]) >= targets[j], 'Return target for segment {0:d} for sample {1:d}'.format(j, i)) i += 1 j += 1 prob += (pulp.lpSum(x) == 1.0, 'Fully invested portfolio requirement') prob.writeLP('JiangGuanDccp.lp') prob.solve() status = pulp.LpStatus[prob.status] print 'Status: {0:s}'.format(status) return np.array([v.varValue for v in prob.variables()]), status
def binpacking(c, w): """ ビンパッキング問題 列生成法で解く(近似解法) 入力 c: ビンの大きさ w: 荷物の大きさのリスト 出力 ビンごとの荷物の大きさリスト """ from pulp import LpAffineExpression n = len(w) rn = range(n) mkp = LpProblem("knapsack", LpMaximize) # 子問題 mkpva = [addvar(cat=LpBinary) for _ in rn] mkp.addConstraint(lpDot(w, mkpva) <= c) mdl = LpProblem("dual", LpMaximize) # 双対問題 mdlva = [addvar() for _ in rn] for i, v in enumerate(mdlva): v.w = w[i] mdl.setObjective(lpSum(mdlva)) for i in rn: mdl.addConstraint(mdlva[i] <= 1) while True: mdl.solve() mkp.setObjective(lpDot([value(v) for v in mdlva], mkpva)) mkp.solve() if mkp.status != 1 or value(mkp.objective) < 1 + 1e-6: break mdl.addConstraint(lpDot([value(v) for v in mkpva], mdlva) <= 1) nwm = LpProblem("primal", LpMinimize) # 主問題 nm = len(mdl.constraints) rm = range(nm) nwmva = [addvar(cat=LpBinary) for _ in rm] nwm.setObjective(lpSum(nwmva)) dict = {} for v, q in mdl.objective.items(): dict[v] = LpAffineExpression() >= q const = list(mdl.constraints.values()) for i, q in enumerate(const): for v in q: dict[v].addterm(nwmva[i], 1) for q in dict.values(): nwm.addConstraint(q) nwm.solve() if nwm.status != 1: return None w0, result = list(w), [[] for _ in range(len(const))] for i, va in enumerate(nwmva): if value(va) < 0.5: continue for v in const[i]: if v.w in w0: w0.remove(v.w) result[i].append(v.w) return [r for r in result if r]
def find(problem, data, MenuDict, target_menu_list, one_da_nutrition_dict): # 対象とする栄養素について、対象の商品リストごとの栄養価を、リスト形式で作成する eiyou_data = {} for key in one_da_nutrition_dict.keys(): # keyに入っている栄養の名称を、データのdictのkeyにする。 #print(key) eiyou = get_nutrition_val_list(MenuDict, target_menu_list, key) if not eiyou: continue eiyou_data[key] = eiyou #print("eiyou_data",eiyou_data) #print("eiyou_data",eiyou_data['エネルギー[kcal]']) # 変数の定義 #LpVariableで自由変数を作成。値は-∞から∞まで #lowBoundで0から∞まで #catで変数の種類指定 # 上限を指定 upbound = 10 xs = up_limit(target_menu_list, upbound) #print("xs:",xs) # 目的関数:カロリーを最小化 # lpdot:二つのリストのない席を求める。 problem += pulp.lpDot(eiyou_data['エネルギー[kcal]'], xs) #制約条件: 一日に必要内容量をそれぞれ満たすこと # 条件カスタマイズ&ON-OFFしやすいように、あえてループ外で起債。 #食塩相当については、「以内」としている。解が存在スカは要注意 # 栄養素を存在するかどうかをkeyがあるかどうかの判定にする # この場合だとメニューを組み合わせたときにエラーが起こ cal_key = [] for key in eiyou_data.keys(): if key == "食塩相当量[g]": continue # メニューの数と栄養素のデータの数が一致しないときは計算しない。 if len(eiyou_data[key]) == len(target_menu_list): #計算したkeyを保存する。 # 計算していないのに栄養素に値がなぜか0じゃないものがあるため cal_key.append(key) #print("eiyou_data[key]",len(eiyou_data[key]),len(target_menu_list),key) problem += pulp.lpDot(eiyou_data[key], xs) >= float( one_da_nutrition_dict[key]) #print("栄養素とxsの内積",pulp.lpDot(eiyou_data[key], xs)) if len(eiyou_data["食塩相当量[g]"]) == len(target_menu_list): cal_key.append("食塩相当量[g]") problem += pulp.lpDot(eiyou_data["食塩相当量[g]"], xs) <= float( one_da_nutrition_dict["食塩相当量[g]"]) status = problem.solve() #print(eiyou_data) return eiyou_data, xs, status, cal_key
def resource_maximize(df, isBinary=False): """リソースを最大化する数理計画問題""" # データの整形 task_name_list, \ alpha_list, \ _, \ df_resource, \ resource_limits = preprocessing_for_mp(df) # 問題定義 problem = pulp.LpProblem(sense=pulp.LpMaximize) # 変数定義 if isBinary: tasks = [ pulp.LpVariable('t{}'.format(idx), cat=pulp.LpBinary) for idx in range(len(task_name_list)) ] else: tasks = [ pulp.LpVariable('t{}'.format(idx), cat=pulp.LpContinuous, lowBound=0, upBound=1) for idx in range(len(task_name_list)) ] # 目的関数定義 demands_each_task = alpha_list * np.array(df_resource.apply(np.sum, axis=1)) problem += pulp.lpDot(demands_each_task, tasks) # 制約条件定義 for (_, demands_each_resource), resource_limit in zip(df_resource.iteritems(), resource_limits): problem += pulp.lpDot(demands_each_resource, tasks) <= resource_limit # 解く status = problem.solve() if pulp.LpStatus[status] != 'Optimal': sys.stderr.write('Error!: この問題は最適化不可能です.以下に作成した問題を示します.') sys.stderr.write(problem) result = { task_name_list[idx]: pulp.value(tasks[idx]) for idx, _ in enumerate(tasks) } return result
def logistics_network( tbde, tbdi, tbfa, dep="需要地", dem="需要", fac="工場", prd="製品", tcs="輸送費", pcs="生産費", lwb="下限", upb="上限", ): """ ロジスティクスネットワーク問題を解く tbde: 需要地 製品 需要 tbdi: 需要地 工場 輸送費 tbfa: 工場 製品 生産費 (下限) (上限) 出力: 解の有無, 輸送表, 生産表 """ facprd = [fac, prd] m = LpProblem() tbpr = tbfa[facprd].sort_values(facprd).drop_duplicates() tbdi2 = pd.merge(tbdi, tbpr, on=fac) tbdi2["VarX"] = addvars(tbdi2.shape[0]) tbfa["VarY"] = addvars(tbfa.shape[0]) tbsm = pd.concat( [tbdi2.groupby(facprd).VarX.sum(), tbfa.groupby(facprd).VarY.sum()], 1) tbde2 = pd.merge(tbde, tbdi2.groupby([dep, prd]).VarX.sum().reset_index()) m += lpDot(tbdi2[tcs], tbdi2.VarX) + lpDot(tbfa[pcs], tbfa.VarY) tbsm.apply(lambda r: m.addConstraint(r.VarX <= r.VarY), 1) tbde2.apply(lambda r: m.addConstraint(r.VarX >= r[dem]), 1) if lwb in tbfa: def flwb(r): r.VarY.lowBound = r[lwb] tbfa[tbfa[lwb] > 0].apply(flwb, 1) if upb in tbfa: def fupb(r): r.VarY.upBound = r[upb] tbfa[tbfa[upb] != np.inf].apply(fupb, 1) m.solve() if m.status == 1: tbdi2["ValX"] = tbdi2.VarX.apply(value) tbfa["ValY"] = tbfa.VarY.apply(value) return m.status == 1, tbdi2, tbfa
def logistics_network(tbde, tbdi, tbfa, dep='需要地', dem='需要', fac='工場', prd='製品', tcs='輸送費', pcs='生産費', lwb='下限', upb='上限'): """ ロジスティクスネットワーク問題を解く tbde: 需要地 製品 需要 tbdi: 需要地 工場 輸送費 tbfa: 工場 製品 生産費 (下限) (上限) 出力: 解の有無, 輸送表, 生産表 """ import numpy as np, pandas as pd from pulp import LpProblem, lpDot, lpSum, value facprd = [fac, prd] m = LpProblem() tbpr = tbfa[facprd].sort_values(facprd).drop_duplicates() tbdi2 = pd.merge(tbdi, tbpr, on=fac) tbdi2['VarX'] = addvars(tbdi2.shape[0]) tbfa['VarY'] = addvars(tbfa.shape[0]) tbsm = pd.concat( [tbdi2.groupby(facprd).VarX.sum(), tbfa.groupby(facprd).VarY.sum()], 1) tbde2 = pd.merge(tbde, tbdi2.groupby([dep, prd]).VarX.sum().reset_index()) m += lpDot(tbdi2[tcs], tbdi2.VarX) + lpDot(tbfa[pcs], tbfa.VarY) tbsm.apply(lambda r: m.addConstraint(r.VarX <= r.VarY), 1) tbde2.apply(lambda r: m.addConstraint(r.VarX >= r[dem]), 1) if lwb in tbfa: def flwb(r): r.VarY.lowBound = r[lwb] tbfa[tbfa[lwb] > 0].apply(flwb, 1) if upb in tbfa: def fupb(r): r.VarY.upBound = r[upb] tbfa[tbfa[upb] != np.inf].apply(fupb, 1) m.solve() if m.status == 1: tbdi2['ValX'] = tbdi2.VarX.apply(value) tbfa['ValY'] = tbfa.VarY.apply(value) return m.status == 1, tbdi2, tbfa
def build_dead_trans_lp(self, transition_id): #uses pulp; doesnt work analysed_transition=self.transitions[transition_id] n_transitions=len(self.transitions) self.firing_count_vector=[pulp.LpVariable("t"+str(i),0) for i in range(0, n_transitions)] weights=[[0 for i in range(0,n_transitions)] for j in range(0,self.n_places)] for i in range(0, n_transitions): trans=self.transitions[i] for (input_id, input_weight) in zip(trans.input_ids, trans.input_weights): weights[input_id][i]=-input_weight for (output_id, output_weight) in zip(trans.output_ids, trans.output_weights): weights[output_id][i]+=output_weight i = 0 while i < n_transitions: analysed_trans_input_weights=[0 for i in range(0,self.n_places)] prob=pulp.LpProblem("prob", pulp.LpMinimize) analysed_transition=self.transitions[i] for (input_id, input_weight) in zip(analysed_transition.input_ids, analysed_transition.input_weights): analysed_trans_input_weights[input_id]=input_weight for j in range(0,self.n_places): prob+=self.initial_marking[j]+pulp.lpDot(weights[j], self.firing_count_vector) >= analysed_trans_input_weights[j] try: status = prob.solve(pulp.GLPK(msg=0)) print(str(status)) i=i+1 except Exception: status = prob.solve(pulp.GLPK(msg=0)) print(str(status)) i=i+1
def facility_location(p, point, cand, func=None): """ 施設配置問題 p-メディアン問題:総距離×量の和の最小化 入力 p: 施設数上限 point: 顧客位置と量のリスト cand: 施設候補位置と容量のリスト func: 顧客位置index,施設候補indexを引数とする重み関数 出力 顧客ごとの施設番号リスト """ if not func: func = lambda i, j: sqrt((point[i][0] - cand[j][0])**2 + (point[i][1] - cand[j][1])**2) rp, rc = range(len(point)), range(len(cand)) m = LpProblem() x = addbinvars(len(point), len(cand)) y = addbinvars(len(cand)) m += lpSum(x[i][j] * point[i][2] * func(i, j) for i in rp for j in rc) m += lpSum(y) <= p for i in rp: m += lpSum(x[i]) == 1 for j in rc: m += lpSum(point[i][2] * x[i][j] for i in rp) <= cand[j][2] * y[j] if m.solve() != 1: return None return [int(value(lpDot(rc, x[i]))) for i in rp]
def facility_location_without_capacity(p, point, cand=None, func=None): """ 容量制約なし施設配置問題 p-メディアン問題:総距離の和の最小化 入力 p: 施設数上限 point: 顧客位置のリスト cand: 施設候補位置のリスト(Noneの場合、pointと同じ) func: 顧客位置index,施設候補indexを引数とする重み関数 出力 顧客ごとの施設番号リスト """ if cand is None: cand = point if not func: func = lambda i, j: sqrt((point[i][0] - cand[j][0])**2 + (point[i][1] - cand[j][1])**2) rp, rc = range(len(point)), range(len(cand)) m = LpProblem() x = addbinvars(len(point), len(cand)) y = addbinvars(len(cand)) m += lpSum(x[i][j] * func(i, j) for i in rp for j in rc) m += lpSum(y) <= p for i in rp: m += lpSum(x[i]) == 1 for j in rc: m += x[i][j] <= y[j] if m.solve() != 1: return None return [int(value(lpDot(rc, x[i]))) for i in rp]
def combinatorial_auction(n, cand, limit=-1): """ 組合せオークション 要素を重複売却せず、購入者ごとの候補数上限を超えないように売却金額を最大化 入力 n: 要素数 cand: (金額, 部分集合, 購入者ID)の候補リスト。購入者IDはなくてもよい limit: 購入者ごとの候補数上限。-1なら無制限。購入者IDをキーにした辞書可 出力 選択された候補リストの番号リスト """ dcv = defaultdict(list) # buyer別候補変数 dcc = defaultdict(list) # item別候補 isdgt = isinstance(limit, int) # buyer別候補数上限 dcl = defaultdict(lambda: limit if isdgt else -1, {} if isdgt else limit) m = LpProblem(sense=LpMaximize) x = addbinvars(len(cand)) # 候補を選ぶかどうか m += lpDot([ca[0] for ca in cand], x) # 目的関数 for v, ca in zip(x, cand): bid = ca[2] if len(ca) > 2 else 0 dcv[bid].append(v) for k in ca[1]: dcc[k].append(v) for k, v in dcv.items(): ll = dcl[k] if ll >= 0: m += lpSum(v) <= ll # 購入者ごとの上限 for v in dcc.values(): m += lpSum(v) <= 1 # 要素の売却先は1まで if m.solve() != 1: return None return [i for i, v in enumerate(x) if value(v) > 0.5]
def set_covering(n, cand, is_partition=False): """ 集合被覆問題 入力 n: 要素数 cand: (重み, 部分集合)の候補リスト is_partition: 集合分割問題かどうか 出力 選択された候補リストの番号リスト """ ad = AutoCountDict() m = LpProblem() vv = [addvar(cat=LpBinary) for _ in cand] m += lpDot([w for w, _ in cand], vv) # obj func ee = [[] for _ in range(n)] for v, (_, c) in zip(vv, cand): for k in c: ee[ad[k]].append(v) for e in ee: if e: if is_partition: m += lpSum(e) == 1 else: m += lpSum(e) >= 1 if m.solve() != 1: return None return [i for i, v in enumerate(vv) if value(v) > 0.5]
def dual_model(m, ignoreUpBound=False): """双対問題作成""" coe = 1 if m.sense == LpMinimize else -1 nwmdl = LpProblem( sense=LpMaximize if m.sense == LpMinimize else LpMinimize) ccs = [[], [], []] for cns in m.constraints.values(): ccs[cns.sense + 1].append(cns) for v in m.variables(): if v.lowBound is not None: ccs[2].append(v >= v.lowBound) if not ignoreUpBound and v.upBound is not None: ccs[0].append(v <= v.upBound) var_count = [0] vvs = [ addvars(len(cc), var_count=var_count, lowBound=0 if i != 1 else None) for i, cc in enumerate(ccs) ] nwmdl += coe * lpSum(k * lpDot([c.constant for c in cc], vv) for k, cc, vv in zip([1, -1, -1], ccs, vvs)) for w in m.variables(): nwmdl += lpSum(k * c.get(w) * v for k, cc, vv in zip([-1, 1, 1], ccs, vvs) for c, v in zip(cc, vv) if c.get(w)) == coe * m.objective.get(w, 0) return nwmdl
def dual_model_nonzero(m, ignoreUpBound=False): """双対問題作成(ただし、全て非負変数)""" from pulp import LpProblem, lpDot, lpSum, LpMaximize, LpMinimize assert all(v.lowBound == 0 for v in m.variables()), 'Must be lowBound==0' if not ignoreUpBound: assert all(v.upBound is None for v in m.variables()) coe = 1 if m.sense == LpMinimize else -1 nwmdl = LpProblem( sense=LpMaximize if m.sense == LpMinimize else LpMinimize) ccs = [[], [], []] for cns in m.constraints.values(): ccs[cns.sense + 1].append(cns) var_count = [0] vvs = [ addvars(len(cc), var_count=var_count, lowBound=0 if i != 1 else None) for i, cc in enumerate(ccs) ] nwmdl += coe * lpSum(k * lpDot([c.constant for c in cc], vv) for k, cc, vv in zip([1, -1, -1], ccs, vvs)) for w in m.variables(): nwmdl += lpSum(k * c.get(w) * v for k, cc, vv in zip([-1, 1, 1], ccs, vvs) for c, v in zip(cc, vv) if c.get(w)) <= coe * m.objective.get(w, 0) return nwmdl
def tsp1(nodes, dist): """ 巡回セールスマン問題 入力 nodes: 点(dist未指定時は、座標)のリスト dist: (i,j)をキー、距離を値とした辞書 出力 距離と点番号リスト """ from more_itertools import iterate, take n = len(nodes) df = pd.DataFrame( [(i, j, dist[i, j]) for i in range(n) for j in range(n) if i != j], columns=["NodeI", "NodeJ", "Dist"], ) m = LpProblem() df["VarIJ"] = addbinvars(len(df)) df["VarJI"] = df.sort_values(["NodeJ", "NodeI"]).VarIJ.values u = [0] + addvars(n - 1) m += lpDot(df.Dist, df.VarIJ) for _, v in df.groupby("NodeI"): m += lpSum(v.VarIJ) == 1 # 出次数制約 m += lpSum(v.VarJI) == 1 # 入次数制約 for i, j, _, vij, vji in df.query("NodeI!=0 & NodeJ!=0").itertuples(False): m += u[i] + 1 - (n - 1) * (1 - vij) + (n - 3) * vji <= u[ j] # 持ち上げポテンシャル制約(MTZ) for _, j, _, v0j, vj0 in df.query("NodeI==0").itertuples(False): m += 1 + (1 - v0j) + (n - 3) * vj0 <= u[j] # 持ち上げ下界制約 for i, _, _, vi0, v0i in df.query("NodeJ==0").itertuples(False): m += u[i] <= (n - 1) - (1 - vi0) - (n - 3) * v0i # 持ち上げ上界制約 m.solve() df["ValIJ"] = df.VarIJ.apply(value) dc = df[df.ValIJ > 0.5].set_index("NodeI").NodeJ.to_dict() return value(m.objective), list(take(n, iterate(lambda k: dc[k], 0)))
def tansportation_problem(costs, x_max, y_max): row = len(costs) col = len(costs[0]) prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize) # lowBound 设置非负 var = [[ pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col) ] for i in range(row)] #折叠成1维 # flatten 1,2,3-----》》 1,2,3,4,5,6 # 4,5,6 flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x] #目标函数 prob += pulp.lpDot(flatten(var), costs.flatten()) #约束 for i in range(row): prob += (pulp.lpSum(var[i]) <= x_max[i]) for j in range(col): prob += (pulp.lpSum([var[i][j] for i in range(row)]) <= y_max[j]) prob.solve() return { 'objective': pulp.value(prob.objective), 'var': [[pulp.value(var[i][j]) for j in range(col)] for i in range(row)] }
def disjointness_LP(sets): if (len(sets) == 0): return prob = LpProblem("Disjointness Problem", LpMaximize) variables = [] for i in range(len(sets)): variables.append(LpVariable("Include Set " + str(i), 0, 1)) #objective prob += lpSum([1 * variables[i] for i in range(len(sets))]) #constraints for j in range(len(sets[0])): #for every qubit, make the sum of actions less than 1 prob += lpDot([sets[i][j] for i in range(len(sets))], [variables[i] for i in range(len(sets))]) <= 1 prob.writeLP("Disjointness.lp") prob.solve(solver=PULP_CBC_CMD(msg=0)) representatives = [] values = [] for v in prob.variables(): i = extract_index(v.name) if (v.varValue != 0.0): representatives.append(i) values.append(v.varValue) return value(prob.objective), representatives, values
def shift_scheduling(ndy, nst, shift, proh, need): """ 勤務スケジューリング問題 入力 ndy: 日数 nst: スタッフ数 shift: シフト(1文字)のリスト proh: 禁止パターン(シフトの文字列)のリスト need: シフトごとの必要人数リスト(日ごと) 出力 日ごとスタッフごとのシフトの番号のテーブル """ nsh = len(shift) rdy, rst, rsh = range(ndy), range(nst), range(nsh) dsh = {sh: k for k, sh in enumerate(shift)} m = LpProblem() v = [[[addvar(cat=LpBinary) for _ in rsh] for _ in rst] for _ in rdy] for i in rdy: for j in rst: m += lpSum(v[i][j]) == 1 for sh, dd in need.items(): m += lpSum(v[i][j][dsh[sh]] for j in rst) >= dd[i] for prh in proh: n, pr = len(prh), [dsh[sh] for sh in prh] for j in rst: for i in range(ndy - n + 1): m += lpSum(v[i + h][j][pr[h]] for h in range(n)) <= n - 1 if m.solve() != 1: return None return [[int(value(lpDot(rsh, v[i][j]))) for j in rst] for i in rdy]
def solver(name: str): size = len(name) # 問題の定義 prob = pulp.LpProblem('tsp', sense=pulp.LpMaximize) # 変数の生成 xs = [] for i in range(size): x = [pulp.LpVariable('x{}_{}'.format(i, j), cat='Binary') for j in range(size)] xs.append(x) # 部分順回路排除用 u = pulp.LpVariable.dicts('u', (i for i in range(size)), lowBound=1, upBound=size, cat='Integer') # スコア生成用の定数配列の生成 cs = [] for i in range(size): cs.append([]) for j in range(size): if name[i] in vowels or name[j] in vowels: cs[i].append(1) else: cs[i].append(0) # 目的関数 prob += pulp.lpSum([pulp.lpDot(c, x) for c, x in zip(cs, xs)]) # 制約条件 # 各文字への行きと帰りはそれぞれ一度しか選ばれない for i in range(size): prob += pulp.lpSum([xs[j][i] for j in range(size)]) <= 1 prob += pulp.lpSum([xs[i][j] for j in range(size)]) <= 1 # n文字(n-1回の連結) prob += pulp.lpSum([pulp.lpSum([x2 for x2 in x1]) for x1 in xs]) == size - 1 # おなじ文字には行かない for i in range(size): prob += xs[i][i] == 0 # 部分順回路排除用 # @see: http://www.ie110704.net/2020/08/15/pulp%E3%81%A7%E6%95%B0%E7%90%86%E6%9C%80%E9%81%A9%E5%8C%96%E5%95%8F%E9%A1%8C%EF%BC%88tsp%E3%80%81vrp%EF%BC%89/ for i in range(size): for j in range(size): if i != j: # ハミルトン閉路ではi,j == 0のとき制約を追加しない prob += u[i] - u[j] <= (1 - xs[i][j]) * size - 1 # 行きか帰りに一度は選ばれる for i in range(size): prob += pulp.lpSum([xs[i][j] for j in range(size)]) + pulp.lpSum([xs[j][i] for j in range(size)]) >= 1 pulp.PULP_CBC_CMD(msg=0, timeLimit=1, options = ['maxsol 1']).solve(prob) xs = [[round(x2.value()) for x2 in x1] for x1 in xs] if prob.status != 1: print(prob.status, pulp.LpStatus[prob.status]) # print("score:", prob.objective.value()) # pprint(xs) # pprint([u1 for u1 in u]) result = target_name(xs, name) return (result, prob.objective.value())
def tsp2(pos): """ 巡回セールスマン問題 入力 pos: 座標のリスト 出力 距離と点番号リスト """ pos = np.array(pos) N = len(pos) m = LpProblem() v = {} for i in range(N): for j in range(i + 1, N): v[i, j] = v[j, i] = LpVariable("v%d%d" % (i, j), cat=LpBinary) m += lpDot( [np.linalg.norm(pos[i] - pos[j]) for i, j in v if i < j], [x for (i, j), x in v.items() if i < j], ) for i in range(N): m += lpSum(v[i, j] for j in range(N) if i != j) == 2 for i in range(N): for j in range(i + 1, N): for k in range(j + 1, N): m += v[i, j] + v[j, k] + v[k, i] <= 2 st = set() while True: m.solve() u = unionfind(N) for i in range(N): for j in range(i + 1, N): if value(v[i, j]) > 0: u.unite(i, j) gg = u.groups() if len(gg) == 1: break for g_ in gg: g = tuple(g_) if g not in st: st.add(g) m += (lpSum( v[i, j] for i in range(N) for j in range(i + 1, N) if (i in g and j not in g) or (i not in g and j in g)) >= 1) break cn = [0] * N for i in range(N): for j in range(i + 1, N): if value(v[i, j]) > 0: if i or cn[i] == 0: cn[i] += j cn[j] += i p, q, r = cn[0], 0, [0] while p != 0: r.append(p) q, p = p, cn[p] - q return value(m.objective), r
def linear_opt(ers, list_constraints, max_mode=True, target_vec=None, num_contests=0): assert max_mode or target_vec is not None, "incorrect inputs" if max_mode or (num_contests == 0): num_contests = 1 max_mode = True else: num_contests = num_contests max_mode = False choice_dict = {} for cont in range(num_contests): choice_dict[cont] = pulp.LpVariable.matrix("Choices" + str(cont), ers.index, lowBound=0, upBound=1, cat='Integer') choice_dict['Total'] = pulp.LpVariable.matrix("ChoicesTotal", ers.index, lowBound=0, upBound=num_contests, cat='Integer') choice_df = pd.DataFrame(choice_dict) if max_mode: prob = pulp.LpProblem("prob", pulp.LpMaximize) prob += pulp.lpDot(choice_dict['Total'], list(ers.values)) else: prob = pulp.LpProblem("prob", pulp.LpMinimize) abs_y = pulp.LpVariable.matrix("abs_y", ers.index, lowBound=0) prob += pulp.lpSum(abs_y) # - pulp.lpDot(choice_dict['Total'], list(ers.values)) for cont in range(num_contests): for lc in list_constraints: if lc[0] == "dot": if lc[1] == ">=": prob += pulp.lpDot(list(lc[2].values), choice_dict[cont]) >= lc[3] if lc[1] == "<=": prob += pulp.lpDot(list(lc[2].values), choice_dict[cont]) <= lc[3] if lc[1] == "==": prob += pulp.lpDot(list(lc[2].values), choice_dict[cont]) == lc[3] for ix in choice_df.index: prob += pulp.lpSum(list(choice_df.iloc[ix].values[:num_contests])) == choice_df.iloc[ix]['Total'] if not max_mode: prob += choice_df.iloc[ix]['Total'] - target_vec.values[ix] <= abs_y[ix] prob += choice_df.iloc[ix]['Total'] - target_vec.values[ix] >= -abs_y[ix] prob.solve() choice_df.index = ers.index solution_opt = choice_df.applymap(lambda x: bool(x.value())).drop('Total', axis=1).astype(int) if max_mode: return solution_opt[0] else: return solution_opt
def knapsack(size, weight, capacity): """ ナップサック問題 価値の最大化 入力 size: 荷物の大きさのリスト weight: 荷物の価値のリスト capacity: 容量 出力 価値の総和と選択した荷物番号リスト """ m = LpProblem(sense=LpMaximize) v = [addvar(cat=LpBinary) for _ in size] m += lpDot(weight, v) m += lpDot(size, v) <= capacity if m.solve() != 1: return None return value( m.objective), [i for i in range(len(size)) if value(v[i]) > 0.5]
def random_model(nv, nc, sense=1, seed=1, rtfr=0, rtco=0.1, rteq=0, feasible=False): """ ランダムなLP作成 nv,nc:変数数、制約条件数 sense:種類(LpMinimize=1) seed:乱数シード rtfr:自由変数割合 rtco:係数行列非零割合 rteq:制約条件等号割合 feasible:実行可能かどうか """ from pulp import LpConstraint, LpStatusOptimal rtco = max(1e-3, rtco) if seed: np.random.seed(seed) var_count = [0] x = np.array(addvars(nv, var_count=var_count)) while True: m = LpProblem(sense=sense) m += lpDot(np.random.rand(nv) * 2 - 1, x) for v in x[np.random.rand(nv) < rtfr]: v.lowBound = None rem = nc while rem > 0: a = np.random.rand(nv) * 2 - 1 a[np.random.rand(nv) >= rtco] = 0 if (a == 0).all(): continue if (a <= 0).all(): a = -a se = int(np.random.rand() >= rteq) * np.random.choice([-1, 1]) m += LpConstraint(lpDot(a, x), se, rhs=np.random.rand()) rem -= 1 if not feasible or m.solve() == LpStatusOptimal: return m
def _set_objective(self): if self.task_rewards is None: logger.info( "Setting objective with equal reward for every task...") self.objective = lpSum(self.start_variables_np) else: logger.info("Setting objective with task rewards...") self.objective = lpDot( np.transpose(a=self.start_variables_np, axes=[1, 0, 2]), self.task_rewards, )
def _init_formulation(g): lp = LpProblem() lp += lpDot( nx.get_edge_attributes(g, 'v').values(), nx.get_edge_attributes(g, 'w').values()) for i in g: lp += lpSum(g[i][j]['v'] for j in g.successors(i)) == 1 lp += lpSum(g[j][i]['v'] for j in g.predecessors(i)) == 1 for i, j in g.edges: # this is for Dantzig-Fulkerson-Johnson. if i < j: lp += g[i][j]['v'] + g[j][i]['v'] <= 1 return lp
def example2(): ''' 河流污染问题 ''' import pulp as lp # variables Variables = ['x1', 'x2'] Object = [1000, 800] x1_limit = [1, 0] x2_limit = [0, 1] sub = [0.8, 1] # problem prob = lp.LpProblem('The Problem 2', lp.LpMinimize) # prob_vars = lp.LpVariable.dicts('Prob', Variables) prob_vars = lp.LpVariable.matrix('Prob', Variables) print prob_vars # object prob += lp.lpDot(Object, prob_vars) # subject prob += lp.lpDot(x1_limit, prob_vars) >= 1 prob += lp.lpDot(x1_limit, prob_vars) <= 2 prob += lp.lpDot(x2_limit, prob_vars) >= 0 prob += lp.lpDot(x2_limit, prob_vars) <= 1.4 prob += lp.lpDot(sub, prob_vars) >= 1.6 print prob # solve prob.solve() print 'Status', lp.LpStatus[prob.status] result = [] for v in prob.variables(): result.append([v.name, v.varValue]) print v.name, '=', v.varValue print 'The Optimal value is : ', lp.value(prob.objective)
def __calcImportance(self, solutionsList): '''Calculates the importance of a weight P2 of referenced work to calculate the importance. ''' if any(self.w + 10**-5 >= 1): self.__importance = -float('inf') return oidx = [i for i in range(self.M)] prob = lp.LpProblem("xNISE procedure", lp.LpMinimize) uR = list(lp.LpVariable.dicts('uR', oidx, cat='Continuous').values()) for value, sols in enumerate(solutionsList): expr = lp.lpDot(self.__normw(sols.w), uR) cons = self.__normf(sols.objs) @ self.__normw(sols.w) prob += expr >= cons for i in oidx: prob += uR[i] <= self.__normf(self.__globalU)[i] prob += lp.lpDot(self.__normw(self.w), uR) grbs = lp.solvers.GUROBI(msg=False, OutputFlag=False, Threads=1) if grbs.available(): prob.solve(grbs) else: cbcs = lp.solvers.PULP_CBC_CMD(threads=1) prob.solve(cbcs, use_mps=False) feasible = False if prob.status in [-1, -2] else True self.__uR = np.array([lp.value(uR[i]) for i in oidx]) if feasible: self.__importance = (self.__normw(self.w) @ self.__point - self.__normw(self.w) @ self.__uR) else: raise ('Non-feasible solution')
def addlines(m, curve, x, y): """区分線形制約(非凸)""" n = len(curve) w = addvars(n - 1) z = addbinvars(n - 2) a = [p[0] for p in curve] b = [p[1] for p in curve] m += x == a[0] + lpSum(w) c = [(b[i + 1] - b[i]) / (a[i + 1] - a[i]) for i in range(n - 1)] m += y == b[0] + lpDot(c, w) for i in range(n - 1): if i < n - 2: m += (a[i + 1] - a[i]) * z[i] <= w[i] m += w[i] <= (a[i + 1] - a[i]) * (1 if i == 0 else z[i - 1])
def ParetoExtremeSet(F): """ Compute the set of extreme non-dominated tables in a given set-factor """ #try: if F.dimension == 1: # compute maximum value u = max([ F.tables[i][0] for i in range(F.num_tables) ]) H = SetFactor([]) H.addTable([u]) # find a maximum strategy for i in range(F.num_tables): if F.tables[i][0] == u: H.labels[0] = F.labels[i] break return H if F.num_tables <= 1: return F if F.num_tables <= 10: return ParetoSet(F) import pulp H = SetFactor(F.scope) N = F.num_tables #assert(N>1) D = F.dimension for t1 in range(N): x = (N-1)*[None] for i in range(N-1): x[i] = pulp.LpVariable("x"+str(i), 0.0, 1.0) prob = pulp.LpProblem("hull", pulp.LpMinimize) for i in range(D): c = [ F.tables[t2][i] for t2 in range(N) if t2 != t1 ] prob += (F.tables[t1][i] - pulp.lpDot(c,x) <= 0.0) prob += (pulp.lpSum(x) == 1.0) prob += x[0] status = prob.solve(pulp.GUROBI_CMD(msg=0)) #print pulp.LpStatus[status] if pulp.LpStatus[status] == "Not Solved": # extreme point found H.addTable(F.tables[t1]) H.labels[H.num_tables-1] = F.labels[t1] #assert( H.num_tables > 0) #print #print F.num_tables-H.num_tables, " dominated tables removed" return H
# 1.1.1 Production Planning Problem (P.1) import pulp prog = pulp.LpProblem('Production Planning Problem', pulp.LpMaximize) A = [[5, 0, 6], [0, 2, 8], [7, 0, 15], [3, 11, 0]] b = [80, 50, 100, 70] c = [70, 120, 30] x = pulp.LpVariable.dicts('X', range(3), 0, 100, pulp.LpInteger) prog += pulp.lpDot(c, [x[i] for i in range(3)]) for row in range(4): prog += pulp.lpDot(A[row], [x[i] for i in range(3)]) <= b[row] for i in range(3): prog += x[i] >= 0 print(prog) prog.solve(); for i in range(3): print(x[i].varValue)
def fit(self, X, y): """Fit the RVM model to the given training data. Pairs of unequal ordering are used for training. For example, if rank(x_1) = rank(x_2) = 1 and rank(x_3) = 2, then the pairs (x_1, x_3) and (x_2, x_3) will be used to train the model. Parameters ---------- X : array-like, shape = [n_samples, n_features] Training vectors. y : array-like, shape = [n_samples] Training ordering with one rank per sample. Returns ------- self : object Returns self. """ gram_matrix = pairwise.pairwise_kernels(X, metric=self.kernel) index_pairs = ranked_index_pairs(y) n_points = X.shape[0] n_pairs = len(index_pairs) if self.verbose: print 'rvm: Setting up the linear program and its objective..' # Set up the linear program and specify the variables, their domains, # and the objective. (We only specify lower bounds because the upper # bound is infinity by default.) self._linprog = pulp.LpProblem('RVM', pulp.LpMinimize) alpha = [pulp.LpVariable('alpha%d' % i, 0) for i in xrange(n_points)] alpha_coefs = [1.0]*n_points xi = [pulp.LpVariable('xi%d' % i, 0) for i in xrange(n_pairs)] xi_coefs = [self.C]*n_pairs self._linprog += pulp.lpDot(alpha_coefs + xi_coefs, alpha + xi) if self.verbose: print 'rvm: Adding constraints to the linear program..' # Add the constraints, one for each pair formed above. for l, (u, v) in enumerate(index_pairs): variables = alpha + [xi[l]] coefs = list(gram_matrix[:, u] - gram_matrix[:, v]) + [1.0] # LpAffineExpression isn't as clear as using lpDot, but for some # reason it's faster. self._linprog += pulp.LpAffineExpression(zip(variables, coefs)) >= 1 if self.verbose: print "rvm: Solving linear program.." status = self._linprog.solve(self.solver) if status != 1: raise Exception('rvm: Unknown error occurred while trying to solve linear program') self._alpha = np.array([pulp.value(a) for a in alpha]) self._rank_vectors = X[self._alpha != 0, :] if self.verbose: print 'rvm: Fit complete.' return self
def solve (self): # # forall (i in get_items()): # item[i] = i.print_mip() # forall (slot in get_slots()): # post: sum (item[slot,:]) = 1 # forall (i in get_items()): # post: sum (item[:,:] if item[:,:].name == i.name) <= 1 problem = pulp.LpProblem("World of Warcraft Optimizer", pulp.LpMaximize) one_handed = [] item_stats = dict() for slot in self.items.keys(): for item in self.items[slot]: self.used[item] = pulp.LpVariable("used[" + item.real_name + "]", 0, 1, 'Integer') item_stats[item] = item.solve(problem, self.used[item]) if self.items[slot]: if slot in [ 13, 22 ]: # One-handed, Off-hand one_handed.append(self.used[item]) else: if slot in [ 11, 12 ]: # Trinket, Ring num_in_slot = 2 else: num_in_slot = 1 problem += pulp.lpSum(self.used[item] for item in self.items[slot]) <= num_in_slot if one_handed: problem += pulp.lpSum(one_handed) <= 2 for item in self.used.keys(): duplicates = [ self.used[i] for i in self.used.keys() if i.get_name() == item.get_name() ] if len(duplicates) > 1: problem += pulp.lpSum(duplicates) <= 1 # # variable: slot_17 in [0,1] # post: slot_17 == sum (used[item] for item in items[17,:]) # for slot in [ 13, 14, 21, 22, 23 ]: # variable: slot_used in [0,1] # post: slot_used = sum (used[item] for item in items[slot,:]) # post: slot_used <= 1 - slot_17 if 17 in self.items.keys(): slot_used_17 = pulp.LpVariable('slot_used[17]', 0, 1, 'Integer') if 17 in self.items.keys(): problem += slot_used_17 == pulp.lpSum(self.used[item] for item in self.items[17]) else: problem += slot_used_17 == 0 for slot in set([ 13, 14, 21, 22, 23 ]) & set(self.items.keys()): slot_used = pulp.LpVariable('slot_used[' + str(slot) + ']', 0, 1, 'Integer') problem += slot_used == pulp.lpSum(self.used[item] for item in self.items[slot]) problem += slot_used <= 1 - slot_used_17 # # variable: total_stats in [0,Inf]^4 # post: sum (item[i]) = total_stats for i in range(len(self.total_stats)): self.total_stats[i] = pulp.LpVariable("total_stats[" + str(i) + "]", 0, cat = 'Integer') problem += pulp.lpSum(s[i] for s in item_stats.values()) + self.base_stats[i] == self.total_stats[i] # # var: penalty in [0,Inf] # post: additional contraints # objective function: weight[:] * total_stats[:] # # solve it self.penalty = pulp.LpVariable('penalty', 0, cat = 'Integer') for ac in self.additional_constraints: def N (name): return '%s[%s]' % (name, '') global I, G exec ac in globals(), locals() self.score = pulp.lpDot(self.weight, self.total_stats) - self.penalty problem += self.score # problem.writeLP('debug.lp') problem.solve() return problem.status
# each total product A = [90, 80] # each order for a company B = [70, 40, 60] # each transfer cost Cost = [[4, 7, 12], [11, 6, 3]] prog = pulp.LpProblem('Transpotation Problem', pulp.LpMinimize) x = pulp.LpVariable.dicts('X', (range(N), range(M)), 0, None, pulp.LpInteger) str_x = [[x[i][j] for j in range(M)] for i in range(N)] prog += pulp.lpDot(Cost, str_x) for i in range(N): prog += pulp.lpDot([1 for j in range(M)], [x[i][j] for j in range(M)]) == A[i] for i in range(M): prog += pulp.lpDot([1 for j in range(N)], [x[j][i] for j in range(N)]) == B[i] prog.solve() print(prog) for i in range(N): for j in range(M): print(x[i][j].varValue)
D = [[75, 50], [8, 7]] # arrange Inventory Plan E1 = [[1 for t in range(T - 1)] + [0] for n in range(N)] E2 = [[0] + [1 for t in range(T - 1)] for n in range(N)] prog = pulp.LpProblem('Multi-period Planning Problem', pulp.LpMinimize); x = pulp.LpVariable.dicts('X', (range(N), range(T)), 0, None, pulp.LpInteger) y = pulp.LpVariable.dicts('Y', (range(N), range(T)), 0, None, pulp.LpInteger) tmp_x = [[x[row][i] for i in range(T)] for row in range(N)] tmp_y = [[y[row][i] for i in range(T)] for row in range(N)] prog += pulp.lpDot(D[0], tmp_x) + pulp.lpDot(D[1], tmp_y) for row_t in range(T): for row_i in range(N): prog += pulp.lpDot(A[row_i], [x[i][row_t] for i in range(N)]) <= C[row_t][row_i] for row_t in range(T): for row_i in range(N): prog += x[row_i][row_t] + E2[row_i][row_t] * y[row_i][(T + row_t - 1) % T] - E1[row_i][row_t] * y[row_i][row_t] == B[row_t][row_i] print(prog) prog.solve() for t in range(T): for n in range(N):