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

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

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

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

1回答

2186閲覧

pulpを用いて条件に最適な行列を求めたい

qklu5

総合スコア2

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2021/04/30 10:20

編集2021/04/30 10:26

前提・実現したいこと

python初心者です。次のような行列をpulpで実現したいです。
・6×6の行列
・制約条件 各行、各列に1は1つ。他は0

100
001
010
・目的関数
1行目a列目にある1と2行目b列目にある1でa>bの関係があれば1ポイント
3行目c列目にある1と4行目d列目にある1と1行目a列目にある1でc>d>aの関係があれば1ポイント
(上2つと同じようなポイント加算の条件が他にもいくつかありますが、今回他の条件は省略しています)
そして、ポイントが最も大きくなる行列をpulpを用いて求める。

このような問題です。色々試行錯誤したのですが、目的関数の部分でどうしてもエラーがでてしまって前に進めず本当に困っています。お詳しい方、何故エラーがでるのか及びどのようなコードを書けばエラーがでず正しくコンパイルできるのかを教えて下さると助かります。

発生している問題・エラーメッセージ

TypeError Traceback (most recent call last) <ipython-input-312-418c9dba27c8> in <module> 22 cc=[] 23 for k1 in ss: ---> 24 a0=pulp.lpSum(ss[0][0:k1]) 25 a1=pulp.lpSum(ss[1][0:k1]) 26 1-(a1-a0)>=cc[0] TypeError: slice indices must be integers or None or have an __index__ method

該当のソースコード

python

1import pulp 2 3ps = [1,2,3,4,5,6] 4ws = [1,2,3,4,5,6] 5prob = pulp.LpProblem('best matrix', sense = pulp.LpMaximize) 6 7ss = [] 8for p in ps: 9 ss1 = [pulp.LpVariable('{}{}'.format(p, x), cat='Binary') for x in range(len(ws))] 10 ss.append(ss1) 11 12for x in range(len(ws)): #各列の和は1 13 xs = [ss[i][x] for i in range(len(ps))] 14 prob += pulp.lpSum(xs) == 1 15 16for y in range(len(ps)): #各行の和は1 17 ys = [ss[y][i] for i in range(len(ws))] 18 prob += pulp.lpSum(ys) == 1 19 20 21#目的関数 22cc=[] 23for k1 in ss: 24 a0=pulp.lpSum(ss[0][0:k1]) 25 a1=pulp.lpSum(ss[1][0:k1]) 26 1-(a1-a0)>=cc[0] 27 28for k2 in ss: 29 a2=pulp.lpSum(ss[2][0:k2]) 30 a3=pulp.lpSum(ss[3][0:k2]) 31 1-(a3-a2)>=cc[1] 32for k3 in ss: 33 a4=pulp.lpSum(ss[3][0:k3]) 34 a5=pulp.lpSum(ss[0][0:k3]) 35 1-(a5-a4)>=cc[1] 36 37prob += pulp.lpSum(cc) 38print(cc) 39 40print(prob) #設定した数理モデルの表示 41status = prob.solve() #問題を解く 42print("Status", pulp.LpStatus[status]) 43print(ws) 44for ss1 in ss: 45 print([v.value() for v in ss1])

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーメッセージには,
"スライスに指定するインデックスは int型,None__index__メソッドを持つオブジェクトのいずれかである必要がある"
と記述されています
ssは二重リストになっているのでk1はリストです
リストはインデックスに指定できないということですね

解決法としては,k1の中身を参照するなどでしょうか

例えば
1行目と2行目の比較なら

~~```
from itertools import product
cc = []
indexs = range(len(ss))
for ia, ib in product(indexs, repeat=2):#組み合わせ生成
if ia > ib:
a = ss[0][ia]
b = ss[1][ib]
f = a*b
cc.append(f)

~~という感じでしょうか~~

投稿2021/05/01 16:26

編集2021/05/02 08:20
taC-h

総合スコア289

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

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

qklu5

2021/05/01 17:21 編集

わざわざご丁寧な回答ありがとうございます。確かに、k1を出力すると[10, 11, 12, 13, 14, 15]になっておりました。このような場合、 cc=[] for k1 in ss: a0=pulp.lpSum(ss[0][0:k1]) a1=pulp.lpSum(ss[1][0:k1]) 1-(a1-a0)>=cc[0] の部分を、「1行目a列目にある1と2行目b列目にある1でa>bの関係があれば1ポイント」のようなコードにするにはどのように改善したら良いでしょうか?
qklu5

2021/05/02 04:23

何度もすいません、それだとNon-constant expressions cannot be multipliedというエラーが出てしまいました。多分pulpは混合整数計画ソルバーなので、目的関数と制約式は線形でなければいけないからかもしれません…。
taC-h

2021/05/02 08:19

線形計画法について調べてみましたが,不等号を含む式を線形計画法で解くことは難しいです 非線形計画法を解くことのできるほかのライブラリに乗り換えたほうがよさそうです...
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問