# 制約条件を定義 problem += p1 + p2 >= 150, 'Demand' problem += p1 <= 100, 'Capacity of Plant 1' problem += p2 <= 50, 'Capacity of Plant 2'
# 問題を解く problem.solve()
# 結果を出力 print(f'Optimal solution found with total cost of {problem.objective.value():.2f}') print(f'Plant 1 generates {p1.value()} MW') print(f'Plant 2 generates {p2.value()} MW')
# 目的関数を設定する prob += pulp.lpSum([weights[a] * returns[a] for a in assets])
# 制約条件を設定する prob += pulp.lpSum([weights[a] for a in assets]) == 1 prob += pulp.lpSum([weights[a] * risks[a] for a in assets]) <= 0.06
# 最適化問題を解く prob.solve()
# 結果を表示する print('Optimal Portfolio:') for a in assets: print('{}: {:.2%}'.format(a, weights[a].value()))
print('Expected Return: {:.2%}'.format(pulp.value(prob.objective))) print('Risk: {:.2%}'.format(pulp.lpSum([weights[a] * risks[a] for a in assets]).value()))
#--------- 入力例1 ---------- N = 6 M = 7 A = [1, 1, 2, 2, 3, 4, 5] B = [2, 4, 3, 5, 6, 5, 6] C = [5, 4, 4, 7, 3, 3, 5] #-----------------------------
from collections import defaultdict
classFordFulkerson: def__init__(self, n): self.n = n self.graph = defaultdict(list) self.visited = [False] * n defadd_edge(self, u, v, c): self.graph[u].append([v, c, len(self.graph[v])]) self.graph[v].append([u, 0, len(self.graph[u]) - 1]) defdfs(self, v, t, f): if v == t: return f self.visited[v] = True for i, (nv, cap, rev) inenumerate(self.graph[v]): if self.visited[nv] or cap == 0: continue d = self.dfs(nv, t, min(f, cap)) if d == 0: continue self.graph[v][i][1] -= d self.graph[nv][rev][1] += d return d return0 defmax_flow(self, s, t): flow = 0 whileTrue: self.visited = [False] * self.n f = self.dfs(s, t, float('inf')) if f == 0: break flow += f return flow
max_flow = FordFulkerson(N + 1) for i inrange(M): max_flow.add_edge(A[i], B[i], C[i])
Q = 5# クエリ―数 query = [ [2, 1, 5], [1, 3], [2, 1, 5], [1, 5], [2, 1, 5] ] #--------------------------- edge = [] # インデックスを0スタートにする for A, B in edges: edge.append((A - 1, B - 1))
# 最後まで残っている辺を求める last = [True] * M for q in query: if q[0] == 1: q[1] -= 1 last[q[1]] = False else: q[1] -= 1 q[2] -= 1
# union-find木 uf = [-1] * N defroot(i): whileTrue: if uf[i] < 0: return i if uf[uf[i]] < 0: return uf[i] uf[i] = uf[uf[i]] i = uf[i]
defunite(i, j): i = root(i) j = root(j) if i == j: return # union by size if uf[i] > uf[j]: i, j = j, i uf[i] += uf[j] uf[j] = i
ans = [] for i inrange(M): if last[i]: A, B = edge[i] unite(A, B)
# クエリ―を逆順に処理する for q inreversed(query): if q[0] == 1: A, B = edge[q[1]] unite(A, B) else: _, U, V = q ans.append("移動可能"if root(U) == root(V) else"移動不可")
# クエリ―の順番を戻して、回答を表示 for s inreversed(ans): print(s)