アプリ版:「スタンプのみでお礼する」機能のリリースについて

glpkを使ってみたく、下記のサイトは読んだですが、自分でモデルを作るとsyntax error になります。
「GLPKで楽しく最適化しよう!」(http://mukun_mmg.at.infoseek.co.jp/mmg/glpk/inde …

1.他のよい日本語の説明文献があれば教えてください。
2.以下のモデルでの間違えを教えてください

#habatori.mod
param N := 3;
set BUNKATSU := 1..3;
set SEIHIN := 1..N;

param CoilWidth := 200;
param CoilLength := 6000;
param Swidth{SEIHIN} ;
param Slength{SEIHIN} ;

var Blength{BUNKATSU}, >=0;
var BX{BUNKATSU, SEIHIN}, >=0 , integer;

minimize Usage: sum{b in BUNKATSU} Blength[b];

s.t. SeihinLen{s in SEIHIN} : sum{b in BUNKATSU} Blength[b]*BX[b,s] >= Slength[s];
s.t. BunkatsuW{b in BUNKATSU} : sum{s in SEIHIN} Swidth{s}*BX[b,s] <= CoilWidth;

#habatori.dat
set Swidth := 55 20 30;
set Slength := 10000 8000 6000;

A 回答 (4件)

Excelで動くなら、それでいいんじゃないか、という気もしますが、


stSeihinLenを次のようにして、強引に足し算にすると、無理やり混合整数計画として表せるんじゃないかと思います。

param BX_MAX := 20; /* 一つの分割から取る部品の最大数、十分に大きな値を設定 */
set BNUM := 1..BX_MAX;
param Blength_MAX := 6000; /* 1つの分割の最大長、十分に大きな値(または CoilLength)を設定 */

var Blength_part{BUNKATSU,SEIHIN,BNUM}, >=0; /* ある分割からある製品用に取ったBNUM番目の部品の長さ(0かBlengthかが入る) */
var Blength_part_nonzero{BUNKATSU,SEIHIN,BNUM}, binary; /* ある分割からある製品用に取ったBNUM番目の部品があるかどうか) */

s.t. stSeihinLen{s in SEIHIN} : sum{b in BUNKATSU, i in BNUM} Blength_part[b, s, i] >= Slength[s];
s.t. part_constraint{b in BUNKATSU, s in SEIHIN, i in BNUM} : Blength_part[b, s, i] <= Blength[b];
s.t. part_constraint2{b in BUNKATSU, s in SEIHIN, i in BNUM} : Blength_part_nonzero[b, s, i] <= (BX[b,s] / i); /* BXがi以上のときのみi番目の部品がとれる */
s.t. part_constraint2_2{b in BUNKATSU, s in SEIHIN, i in BNUM : Swidth[s] * i > CoilWidth} : Blength_part_nonzero[b, s, i] = 0; /* 1品種でとろうとした場合の最大の番号を超える分はゼロ */
s.t. part_constraint3{b in BUNKATSU, s in SEIHIN, i in BNUM} : Blength_part[b, s, i] <= Blength_part_nonzero[b, s, i] * Blength_MAX; /* BX[b,s]番目以降の部品は長さ0 */


結果の主要部を書いておくので正しそうかどうかを判断する材料にしてください。
答えが出るまで35分かかりました。
上でpart_constraint2_2とした制約式は入れないで(入れ忘れて)動かしましたが、多分、条件としては上と等価だと思います。

No. Column name Activity Lower bound Upper bound
------ ------------ ------------- ------------- -------------
1 Blength[1] 2666.67 0
2 Blength[2] 1666.67 0
3 Blength[3] 444.444 0
4 BX[1,1] * 2 0
5 BX[1,2] * 3 0
6 BX[1,3] * 1 0
7 BX[1,4] * 0 0
8 BX[2,1] * 2 0
9 BX[2,2] * 0 0
10 BX[2,3] * 2 0
11 BX[2,4] * 3 0
12 BX[3,1] * 3 0
13 BX[3,2] * 0 0
14 BX[3,3] * 0 0
15 BX[3,4] * 3 0

参考書については良く分かりませんが、GLPKの参考書というより、
線形計画の参考書を探した方が良さそうな気がします。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
この課題については、線形性の制約上無理だった
Blength[b] * BX[b,s] をどうやって別形式で表現しようかと悩んでいたのですが、いい方法が見つからずどうすることもできなかったところです。
なるほど回答者さんのように
Blength_part_nonzero[b, s, i] <= (BX[b,s] / i) と
Blength_part[b, s, i] <= Blength_part_nonzero[b, s, i] * Blength_MAX;
の2つに分解して無理やり和の形式にもっていくことができるんですね。私は線形計画の定式化の経験がないもので、こういう計算量が大きくなるようなデータ形式を持つことは全く発想外で、式を読み解いて感心することしきりでした。
どうもありがとうございます。

参考文献は、やはりまず線形計画の参考書ですか。GLPKは英語マニュアルを読むしかないですね。これはがんばるしかないか。
なお、以下のHPでGLPKの出力を説明しているのを発見しました。
http://www.swa.gr.jp/lop/lop_a032.html

いろいろ述べましたが、どうもありがとうございました。

お礼日時:2008/07/19 17:40

最初の投稿時の入力ファイルで実験したところ、自分の環境では、



multiplication of linear forms not allowed
Context: ...IN } : sum { b in BUNKATSU } Blength [ b ] * BX [ b , s ] >=

というエラーになりました。
線型計画法なので、 varとvarとのかけ算は許されないというので、
それが最大の原因のように思います。
どういう問題が解きたいのかが良くわからなかったので解決策は示せません。

paramは大文字で始めて、varは小文字で始めるとか、
命名規則を適当に定めてやったら良いのではないでしょうか。

回答に対する補足を見たら直っていたみたいですが、
最初の投稿時は
Swidth[s]であるべきところがSwidth{s}になっていたり
データファイルでparamであるべきところがsetになっていたり(:=の後ろについてもparamの文法と違う)していました。
あと、CoilLengthという変数が使われていなかったりしました。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
multiplication of linear forms not allowed
というエラーについては、当方でも同じようにでていたのですが、最初の質問でも述べたように、そもそもGLPKの規則がよくわかっていなかったため、対処のしようがなかったのです。指摘の後半部分はその通りで初回の回答で気づいて直した次第です。
今回varとvarの掛け算がだめとの示唆を頂き、言われてみればその通りであり、モデル自身を構築しなおす必要があると思っています。
LPに適したモデル構築の問題か、GLPKの文法問題かの区別もつかいない初心者ですので、何かよい文法書があればご教授お願いします。

お礼日時:2008/07/16 23:00

うごいた。

dat変えた。
いちおう、デバッガは動いたけど、初期値が変なので解は出なかった。cとパールしか使わないからよく分からないんだけど。

set SEIHIN:= a b c d;
param BunN := 3;
param SeiN := 4;
param CoilWidth := 200;
param CoilLength := 6000;
param Swidth:=
a:=1
b:=2
c:=3
d:=4;
param Slength:=
a:=1
b:=2
c:=3
d:=4;
    • good
    • 0

#habatori.dat


param CoilWidth := 200;
param CoilLength := 6000;
param n:=(具体的な数値を入れる);
param : x y z:=
1 111
2 111

(具体的な数値まで) 1 1 1 ;

#habatori.mod
param n;
param CoilWidth;
param CoilLength;
param x{1..n};
param y{1..n};
param z{1..n};
var s{1..n};
minimize PROFIT:sum{i in 1..n}s[i];
s.t. A1{i in 1..n}:x[i]*s[i]+y[i]*s[i]+z[i]*s[i]>=(何が入るのか上記だけでは分からない。);
s.t. A1{i in 1..n}:x[i]*s[i]+y[i]*s[i]+z[i]*s[i]<=CoilWidth;

条件式がまずおかしい。数学力もプログラミング能力も両方足りてない。

この回答への補足

回答ありがとうございます。
ご指摘の通り、param への入力方法のミスと、エラーのおきたsumを数式展開をしてみましたが、やはりエラーがでます。エクセルのソルバーで試すと答えはでるので、モデル自体は間違っていないと思うのですが、今日も一日ずっと色々試してたのですがGLPKではどうもうまくいきません。よろしくご教授願います。
#habatori.mod
param SeiN;
param BunN;
set BUNKATSU := 1..BunN;
set SEIHIN := 1..SeiN;

param CoilWidth;
param CoilLength;
param Swidth{SEIHIN} ;
param Slength{SEIHIN} ;

var Blength{BUNKATSU}, >=0;
var BX{BUNKATSU, SEIHIN}, >=0 , integer;

minimize Usage: sum{b in BUNKATSU} Blength[b];

s.t. JUNJO{b in BUNKATSU : b < BunN} : Blength[b] >= Blength[b+1];
s.t. stBunkatsuW{b in BUNKATSU} : sum{s in SEIHIN} Swidth[s] * BX[b,s] <= CoilWidth;
s.t. stSeihinLen{s in SEIHIN} : Blength[1]*BX[1,s]+ Blength[2]*BX[2,s]+ Blength[3]*BX[3,s] >= Slength[s];
/*
s.t. stSeihinLen{s in SEIHIN} : sum{b in BUNKATSU} Blength[b] * BX[b,s] >= Slength[s];
*/

data;
param BunN := 3;
param SeiN := 4;
param CoilWidth := 200;
param CoilLength := 6000;
param Swidth := 1 55, 2 20,3 30,4 10;
param Slength := 1 10000, 2 8000, 3 6000,4 6000;

補足日時:2008/07/05 17:24
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!