前提・実現したいこと
分子限定法で、ナップザックの最適化問題を解こうとしています。
以下のエラーメッセージが発生しました。
end_of_branchには配列が入っているはずなのですが、len()でエラーが発生してしまいます。
どうすれば良いかご教授いただけると幸いです。
発生している問題・エラーメッセージ
TypeError Traceback (most recent call last)
<ipython-input-36-c442ae7a992d> in <module>()
46
47
---> 48 print(branch_and_bound_for_01knapsack_problem(cost_, value_, budget_))
1 frames
<ipython-input-35-38bafabdce75> in is_feasible(end_of_branch, cost, budget)
1 #割り当てが途中までの段階で、costの合計がbudgetを超えてしまわないかを判定する
2 def is_feasible(end_of_branch, cost, budget):
----> 3 for t in range(len(end_of_branch)): #採用されているか
4 if end_of_branch[t] == 1: #採用されている場合
5 budget -= cost[t] #予算から引く
TypeError: object of type 'NoneType' has no len()
該当のソースコード
import random
i = 123456
n = 6
random.seed(i)
cost_ = []
value_ = []
for t in range(n):
cost_.append(random.randint(1,8))
value_.append(random.randint(2,16))
print(t,'番目の要素x_', t, 'のコストは',cost_[-1],'、価値は',value_[-1])
budget_ = n*3
print('cost_ =', cost_)
print('value_ =', value_)
print('budget_ =', budget_)
import numpy as np
//コストあたりの価値を求めてリストにする
value_per_cost = []
for t in range(n):
value_per_cost.append(value_[t]/cost_[t]) #配列に一つずつ追加
print('value_per_cost =', value_per_cost) #出力
// コストあたりの価値が高い順に、indexを取得
index = np.argsort(value_per_cost)[::-1]
'print(index)して, value_per_costと見比べよう'
print(index)
//割り当てが途中までの段階で、costの合計がbudgetを超えてしまわないかを判定する
def is_feasible(end_of_branch, cost, budget):
for t in range(len(end_of_branch)): #採用されているか
if end_of_branch[t] == 1: #採用されている場合
budget -= cost[t] #予算から引く
if budget<0 : #予算オーバー return True else: #予算以内 return False
//採否の割り当てが済んだ段階で、割り当て済み分の価値の合計を計算する
def objective_value(end_of_branch, value):
obj_val = 0 #価値の合計を初期化
for t in range(len(end_of_branch)):
if end_of_branch[t] == 1: #採用されている場合
obj_val += value[t] #合計にプラス
return obj_val
//緩和問題を解く(cost,valueがコスパ順にソート済みの場合)
def linear_relaxed_value(end_of_branch, cost, value, index, budget):
//割り当て済みの分だけ価値を計算し、その分のcostをbudgetから差し引く
relaxed_value = 0 #価値の合計を初期化
for t in range(len(end_of_branch)): #採用されているか
if end_of_branch[t] == 1: #採用されている場合
budget -= cost[t] #予算から引く
relaxed_value += value[t] #合計にプラス
//まだ割り当てていない分を、コスパのよい順に採用していく i = len(end_of_branch)-1 while i<n: if budget==0: #予算を使い切ったとき break elif cost[i]<=budget: #予算に余裕があるとき budget -= cost[i] #予算から引く relaxed_value += value[i] #合計にプラス else: //コストの都合で1に満たない分しか採用できない場合は、その分の価値だけを積み増す percent = budget/cost[i] #積み増すことができる割合 budget = 0 relaxed_value += value[i]*percent //緩和問題で得られる価値の合計を返す return relaxed_value
def branch_and_bound_for_01knapsack_problem(cost, value, budget):
//コスパの高い順に、要素の属性(コスト、価値など)を呼び出せるように準備
cost_percost = []
value_percost = []
for i in index:
cost_percost.append(cost[i])
value_percost.append(value[i])
stack = [[]] #未検討の分枝のリストであり、各分枝の先端における採否の割り当てのリストを要素とする best_value = 0 best_solution = [0]*n stack.append([0]) stack.append([1]) //未検討の分枝がなくなるまで、未検討の分枝から一つ取り出して以下の操作をする while len(stack) != 0 : end_of_branch = stack.pop() //実行不能ならその分枝の検討を飛ばす if is_feasible(end_of_branch, cost_percost, budget) : print(end_of_branch, 'is not feasible') continue //緩和問題を解いた結果、暫定解より良くなる見込みがなければ飛ばす if linear_relaxed_value(end_of_branch, cost_percost, value_percost, index, budget) <= best_value: print(end_of_branch, 'is bounded') continue //割り当てが済んだ分枝について価値を計算し、暫定解と比較して更新する if len(end_of_branch)==n : obj_val = objective_value(end_of_branch, value_percost) if obj_val > best_value: best_value = obj_val best_solution = end_of_branch print('the best solution at the moment is ', end_of_branch) //分枝を生やす else: newbranch_1=end_of_branch.append(0) newbranch_2=end_of_branch.append(1) stack.append(newbranch_1) stack.append(newbranch_2) print(stack) return (best_value, best_solution)
print(branch_and_bound_for_01knapsack_problem(cost_, value_, budget_))
補足情報(FW/ツールのバージョンなど)
Jupiter notebook上でやっています。
ソースコード中に // が出てきますが、実装上では # です。
回答1件
あなたの回答
tips
プレビュー