macdonald問題の GMPL による解
- ひきつづき GMPLのお勉強
- データの元となる CSV の作成
#!/usr/bin/perl
use warnings;
use strict;
use HTML::TagParser;
# curl -O "https://www.mcdonalds.co.jp/quality/allergy_Nutrition/nutrient/index.html"
my $html = HTML::TagParser->new( 'index.html' ); # Change this to your file
print "itemname,weight,energy,protein,lipid,carbonate,natrium,kalium,calcium,phosphorus,fe,vita,vitb1,vitb2,niacin,vitc,chol,fiber,nacl\n";
my $nrow = 0;
for my $tr ( $html->getElementsByTagName("tr" ) ) {
my $ncol = 0;
for my $td ( $tr->subTree->getElementsByTagName("td") ) {
last if $ncol == 19;
my $c = $td->innerText();
if ($c =~ /^備考1/)
{
exit(0); # abort program
}
print "," if $ncol++ != 0;
print $c;
}
print "\n" if $nrow>2;
$nrow++;
}
- GMPLには if {} 文がないため、for で代用する
- たとえば NaCl>8g protein>40g calorie>1400kcalを満たす最低カロリーの組み合わせを選ぶプログラムは下記
- 実行:
glpsol -m reader.mod
reader.mod:7: duplicate tuple 'カフェラテ(M)' detected
などと出る際は複数出現しているエントリをcsvから削除する必要がある
- reader.modは下記
set I;
var x{I} ,integer, >=0;
param ene{I};
param prot{I};
param nacl{I};
table data IN "CSV" "macdonald.csv" :
I <- [itemname], ene ~ energy, prot ~ protein, nacl ~ nacl;
minimize CALORIE: sum{i in I} ene[i]*x[i];
s.t. CONSTRAINT1: sum{i in I} nacl[i]*x[i] >= 8.0;
s.t. CONSTRAINT2: sum{i in I} prot[i]*x[i] >= 40.0;
s.t. CONSTRAINT3: sum{i in I} ene[i]*x[i] >= 1400.0;
# printf {i in I} "%s %.1f %.1f %.1f\n", i, ene[i], prot[i], nacl[i];
solve;
for { i in I }
{
for {{0}: x[i]>0} { # GMPL には if block がないため、 if x[i]>0 のかわりに forを使う
printf "%s %d個 %.1f %.1f %.1f\n", i, x[i], x[i]*ene[i], x[i]*prot[i], x[i]*nacl[i];
}
}
end;
macdonald.csv
itemname,weight,energy,protein,lipid,carbonate,natrium,kalium,calcium,phosphorus,fe,vita,vitb1,vitb2,niacin,vitc,chol,fiber,nacl
えびフィレオ®,174,395,12.5,17.4,47.7,919,119,64,102,0.8,8,0.09,0.06,1,1,66,2.9,2.3
ごはんてりやき,213,545,14.5,29.4,55.8,986,237,33,149,0.9,10,0.16,0.16,3.3,1,56,0.8,2.5
ごはんフィッシュ 和風黒胡椒,194,430,15.4,15.7,57.3,944,206,102,248,0.4,52,0.08,0.1,1,0,45,1.5,2.4
...省略...
実行例
GLPSOL--GLPK LP/MIP Solver 5.0
...
Time used: 0.0 secs
Memory used: 0.8 Mb (866271 bytes)
塩・コショウ 7個 7.0 0.0 4.2
アールグレイ アイスティー(ストレート)(L) 2個 6.0 0.0 0.0
アールグレイ アイスティー(ミルク)(M) 27個 351.0 5.4 0.0
コカ・コーラ ゼロ(L) 19個 0.0 0.0 1.9
ホットティー(ミルク)(M) 1個 14.0 0.5 0.0
リキッドレモン 1個 1.0 0.0 0.0
ダージリンティー(M) 99個 0.0 19.8 0.0
ダージリンティー(テイクアウト用)(M) 1個 0.0 0.3 0.0
チョコフラッペ(L) 1個 574.0 7.8 1.1
チョコフラッペ(M) 1個 447.0 6.3 0.8
Model has been successfully processed
- 飲み物禁止とするべきか..