質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

1533閲覧

Pythonでのlen()におけるTypeError

ryotazumi

総合スコア8

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/06/19 17:12

前提・実現したいこと

分子限定法で、ナップザックの最適化問題を解こうとしています。
以下のエラーメッセージが発生しました。
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上でやっています。
ソースコード中に // が出てきますが、実装上では # です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiracamus

2020/06/19 18:18

エラーメッセージは end_of_branch 変数の値が None だと言っていますよ。 デバッガで止めたり、デバッグprintで確認してみてはいかがですか?
meg_

2020/06/20 00:38

コードは「コードの挿入」で記入してください。
ryotazumi

2020/06/20 17:43

end_of_branchでプリントすると[1]となるのですが、配列として入っていないのでしょうか? 自分ではあまりわからず、ご教授いただけると嬉しいです。
shiracamus

2020/06/21 04:31

end_of_branch = stack.pop() してますが、stack の中にリストが入っているのですか? この直後で print(end_of_branch) してみてください。
ryotazumi

2020/06/21 04:42

確認したところ、分枝を増やす箇所で間違いがあったことに気がつきました。助かりました。ありがとうございます。
guest

回答1

0

ベストアンサー

TypeError: object of type 'NoneType' has no len()

'NoneType' には len()がない、といってます。
本当に配列が入ってるんでしょうか。
チェックしてみてください

投稿2020/06/19 21:40

y_waiwai

総合スコア88042

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryotazumi

2020/06/20 17:46

ご回答ありがとうございます。配列は入っていなさそうなのですが、なぜそうなっているのかわからず苦労しています。ご教授いただけると嬉しいです。
y_waiwai

2020/06/20 21:43

end_of_branchになにか代入してるところが見当たりませんが、 今の状態ではコードが読めないんでなんとも言えません。 質問を編集し、<code>ボタン押して、’’’の枠の中にコードを貼り付けてください。
ryotazumi

2020/06/23 05:32

配列に何が入っているか確かめたところ、分枝を増やすところで誤りが見つかりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問