Keyword: 酪農, 最適化, 飼料配合, コスト最小化, LP
畜産分野の最適化問題:最適な飼料配合
問題の概要
ここでは、畜産業における飼料配合の最適化問題について取り上げます。家畜の健康と生産性を維持するためには、適切な栄養価を持つ飼料を与えることが重要ですが、飼料のコストは畜産経営の大きな負担となっています。そのため、家畜の栄養要求量を満たしつつ、飼料コストを最小化することが求められます。この問題を解決するために、線形計画法を用いて、様々な飼料原料の組み合わせを最適化し、コストを最小限に抑えながら必要な栄養価を確保する方法を取り上げます。
乳牛の飼料配合最適化(具体例)
ここでは、最適化問題の具体的な例として、乳牛の飼料配合問題を取り上げます。
600kgの乳牛を対象とした飼料配合を最適化する問題を考えます。目的は、乳牛の栄養要求量を満たしつつ、飼料のコストを最小化することです。以下の表は、この問題で考慮される飼料原料の詳細情報を示しています。
飼料原料 | 飼料区分 | タンパク質量 (kg) | 脂質 (kg) | 繊維 (kg) | 価格 (円/kg) | 配合上限 (%) | 配合下限 (%) |
---|---|---|---|---|---|---|---|
トウモロコシ | 濃厚飼料 | 0.095 | 0.042 | 0.026 | 44 | 40 | 15 |
大豆粕 | 濃厚飼料 | 0.48 | 0.013 | 0.07 | 88 | 20 | 5 |
ビートパルプ | 濃厚飼料 | 0.11 | 0.009 | 0.2 | 33 | 30 | 10 |
綿実粕 | 濃厚飼料 | 0.41 | 0.02 | 0.13 | 66 | 15 | 5 |
フスマ | 濃厚飼料 | 0.17 | 0.045 | 0.085 | 38 | 20 | 0 |
米ぬか | 濃厚飼料 | 0.14 | 0.2 | 0.22 | 27 | 10 | 0 |
アルファルファヘイ | 粗飼料 | 0.2 | 0.028 | 0.28 | 66 | 30 | 10 |
チモシー乾草 | 粗飼料 | 0.1 | 0.022 | 0.35 | 55 | 40 | 15 |
オーチャードグラス乾草 | 粗飼料 | 0.115 | 0.028 | 0.33 | 60 | 40 | 5 |
トウモロコシサイレージ | 粗飼料 | 0.09 | 0.035 | 0.24 | 28 | 30 | 10 |
セルロース粉末 | 添加物 | 0 | 0 | 1 | 165 | 1 | 0 |
この問題を解くにあたって、以下の制約条件を考慮する必要があります。
- 総飼料量(1日あたり):35kg
- 必要な栄養量(1日あたり):
- タンパク質 (p_i) の合計量が 5kg 以上
- 脂質 (f_i) の合計量が 1kg 以上
- 繊維 (d_i) の合計量が 6kg 以上 ※ p_i, f_i, d_i は、それぞれ i 番目の飼料原料 1kg あたりに含まれるタンパク質量、脂質量、繊維量を表します。
- 粗飼料の割合は、総飼料量の50%以上60%以下でなければなりません。
- 各飼料の配合割合は、表に示された上限と下限の範囲内でなければなりません。
目的は、これらの制約条件を満たしながら、飼料のコストを最小化することです。この問題を解くことで、乳牛の栄養ニーズを満たし、指定された制約条件を尊重しながら、総コストを最小限に抑える最適な飼料配合を決定することができます。
問題の定式化
パラメータ
パラメータ | 説明 | 値 |
---|---|---|
表参照 | ||
表参照 | ||
表参照 | ||
表参照 | ||
表参照 | ||
表参照 |
決定変数
変数 | 説明 | 範囲 |
---|---|---|
目的関数
目的 | 式 |
---|---|
飼料コストの最小化 |
飼料費は農家の主要な経費であり、過剰な費用は利益を圧迫するため、飼料コストを最小化することが目標です。
制約条件
制約 | 式 | 説明 |
---|---|---|
総飼料量 | 乳牛の1日あたりの総飼料量は35kgに制限されています。 | |
タンパク質要求量 | 乳牛の1日あたりのタンパク質要求量は5kg以上です。 | |
脂質要求量 | 乳牛の1日あたりの脂質要求量は1kg以上です。 | |
繊維要求量 | 乳牛の1日あたりの繊維要求量は6kg以上です。 | |
粗飼料の割合下限 | 粗飼料の割合は総飼料量の50%以上でなければなりません。 | |
粗飼料の割合上限 | 粗飼料の割合は総飼料量の60%以下でなければなりません。 | |
飼料の配合上限 | 各飼料原料の配合量は、指定された上限と下限の範囲内でなければなりません。 | |
非負条件 | 各飼料原料の量は非負でなければなりません。 |
これらの制約条件は、乳牛の栄養要求量を満たし、適切な飼料バランスを保ち、各飼料原料の配合規則に従うことを保証します。
コード例
以下に、この線形計画問題を nAG Library for Python の LP問題専用ソルバー関数 lp_solve を用いて解くコード例を示します。
この問題の制約条件行列は密行列(デンス行列)であるため、lp_solve のような汎用的な LP ソルバーが適しています。nAG Library には他に制約条件行列がスパースな場合に特化したスパース LP ソルバーもありますが、今回の問題には lp_solve を選択しました。
import numpy as np
from naginterfaces.library import opt
# 総飼料量の設定(単位: kg)
= 35
total_feed_amount
# 栄養成分要求の最小値と最大値設定(単位: kg)
= [5, 1, 6] # 最小要求量
min_nutrient_requirements = [np.inf, np.inf, np.inf] # 最大要求量は無制限
max_nutrient_requirements
# 粗飼料の比率範囲設定(最小及び最大)
= 0.5
rough_feed_ratio_min = 0.6
rough_feed_ratio_max
# 飼料原料の情報設定
= {
feed_info 'トウモロコシ': {'type': '濃厚飼料', 'price': 44, 'protein': 0.095, 'fat': 0.042, 'fiber': 0.026, 'max_proportion': 0.40, 'min_proportion': 0.15},
'大豆粕': {'type': '濃厚飼料', 'price': 88, 'protein': 0.48, 'fat': 0.013, 'fiber': 0.07, 'max_proportion': 0.20, 'min_proportion': 0.05},
'ビートパルプ': {'type': '濃厚飼料', 'price': 33, 'protein': 0.11, 'fat': 0.009, 'fiber': 0.2, 'max_proportion': 0.30, 'min_proportion': 0.10},
'綿実粕': {'type': '濃厚飼料', 'price': 66, 'protein': 0.41, 'fat': 0.02, 'fiber': 0.13, 'max_proportion': 0.15, 'min_proportion': 0.05},
'フスマ': {'type': '濃厚飼料', 'price': 38, 'protein': 0.17, 'fat': 0.045, 'fiber': 0.085, 'max_proportion': 0.20, 'min_proportion': 0},
'米ぬか': {'type': '濃厚飼料', 'price': 27, 'protein': 0.14, 'fat': 0.2, 'fiber': 0.22, 'max_proportion': 0.10, 'min_proportion': 0},
'アルファルファヘイ': {'type': '粗飼料', 'price': 66, 'protein': 0.2, 'fat': 0.028, 'fiber': 0.28, 'max_proportion': 0.30, 'min_proportion': 0.10},
'チモシー乾草': {'type': '粗飼料', 'price': 55, 'protein': 0.1, 'fat': 0.022, 'fiber': 0.35, 'max_proportion': 0.40, 'min_proportion': 0.15},
'オーチャードグラス乾草': {'type': '粗飼料', 'price': 60, 'protein': 0.115, 'fat': 0.028, 'fiber': 0.33, 'max_proportion': 0.40, 'min_proportion': 0.05},
'トウモロコシサイレージ': {'type': '粗飼料', 'price': 28, 'protein': 0.09, 'fat': 0.035, 'fiber': 0.24, 'max_proportion': 0.30, 'min_proportion': 0.10},
'セルロース粉末': {'type': '添加物', 'price': 165, 'protein': 0, 'fat': 0, 'fiber': 1, 'max_proportion': 0.01, 'min_proportion': 0}
}
# 飼料名のリスト生成
= list(feed_info.keys())
feed_names
# 粗飼料と濃厚飼料のインデックスの生成
= [i + 1 for i, feed in enumerate(feed_names) if feed_info[feed]['type'] == '粗飼料']
rough_feed_indices = [i + 1 for i, feed in enumerate(feed_names) if feed_info[feed]['type'] == '濃厚飼料']
concentrated_feed_indices
# その他各配列の生成
= np.array([feed_info[feed]['price'] for feed in feed_names])
feed_prices = np.array([feed_info[feed]['protein'] for feed in feed_names])
protein_content = np.array([feed_info[feed]['fat'] for feed in feed_names])
fat_content = np.array([feed_info[feed]['fiber'] for feed in feed_names])
fiber_content = np.array([feed_info[feed]['max_proportion'] for feed in feed_names])
max_proportions = np.array([feed_info[feed]['min_proportion'] for feed in feed_names])
min_proportions
# 問題の初期化
= len(feed_prices)
num_variables
# 目的関数の係数(コスト最小化のため)
= feed_prices
cvec
# 各飼料の割合に基づいた変数の上下限設定
= min_proportions * total_feed_amount
bl_vars = max_proportions * total_feed_amount
bu_vars
# 制約の下限と上限
= np.concatenate([
bl_constraints # 総飼料量の正確な値
[total_feed_amount], 5], # タンパク質要求量の最小値
[1], # 脂質要求量の最小値
[6], # 繊維要求量の最小値
[* total_feed_amount, -rough_feed_ratio_max * total_feed_amount] # 最小及び最大配合量(kg)
[rough_feed_ratio_min
])= np.concatenate([
bu_constraints # 総飼料量の正確な値
[total_feed_amount], # タンパク質要求量の最大値は無限
[np.inf], # 脂質要求量の最大値は無限
[np.inf], # 繊維要求量の最大値は無限
[np.inf], -rough_feed_ratio_min * total_feed_amount] # 設定可能な最大配合量(kg)
[np.inf,
])
# 制約係数行列
= np.vstack([
a # 総飼料量
np.ones(num_variables), # タンパク質要求量
protein_content, # 脂質要求量
fat_content, # 繊維要求量
fiber_content, 1 if i in rough_feed_indices else 0 for i in range(1, num_variables + 1)], # 粗飼料
[-1 if i in concentrated_feed_indices else 0 for i in range(1, num_variables + 1)] # 濃厚飼料
[
])
# 初期解の設定
= [0] * num_variables
x0
# コミュニケーションオブジェクトの初期化
= opt.nlp1_init('lp_solve')
comm "Print Level = 0",comm)
opt.lp_option_string(
# 線形プログラミング問題を解く
= np.concatenate([bl_vars, bl_constraints]) # 変数の下限に続いて制約の下限
bl_total = np.concatenate([bu_vars, bu_constraints]) # 変数の上限に続いて制約の上限
bu_total
= opt.lp_solve(bl_total, bu_total, x0, comm, a=a, cvec=cvec)
_, optimal_solution, _, obj, _, _
# 結果の表示
print('最適解:')
print(optimal_solution)
print('最適な飼料の配合:')
= 0
total_cost for i, amount in enumerate(optimal_solution):
if amount > 1e-2: # 非常に小さい値を除外
= amount * feed_prices[i]
cost += cost
total_cost print(f'{feed_names[i]}: {amount:.2f} kg, コスト: \{cost:.0f}')
print(f'総飼料量: {sum(optimal_solution):.2f} kg') # 理論的には35kg
print(f'総コスト: \{obj:.0f}')
結果例
上記のコードを実行すると、以下のような出力が得られます。
最適解:
[5.25 1.75 5.25 1.75 0. 3.5 3.5 5.25 1.75 7. 0. ]
最適な飼料の配合:
トウモロコシ: 5.25 kg, コスト: \231
大豆粕: 1.75 kg, コスト: \154
ビートパルプ: 5.25 kg, コスト: \173
綿実粕: 1.75 kg, コスト: \116
米ぬか: 3.50 kg, コスト: \94
アルファルファヘイ: 3.50 kg, コスト: \231
チモシー乾草: 5.25 kg, コスト: \289
オーチャードグラス乾草: 1.75 kg, コスト: \105
トウモロコシサイレージ: 7.00 kg, コスト: \196
総飼料量: 35.00 kg
総コスト: \1589
この結果は、与えられた制約条件下で飼料コストを最小化する最適な飼料配合を示しています。各飼料原料の配合量とそれに対応するコストが明示され、総飼料量が35kgで総コストが1589円であることが示されています。この最適解は、乳牛の栄養要求量を満たしつつ、飼料コストを最小限に抑えるものです。
まとめ
ここでは、畜産業における飼料配合の最適化問題について取り上げました。家畜の健康と生産性を維持しつつ、飼料コストを最小化するという課題に対して、線形計画法を用いて問題を定式化し、飼料原料の栄養価、価格、配合上限、最低配合割合などの制約条件を考慮しながら、最適な飼料配合を求めることができました。
この手法は、様々な家畜や飼料原料、コスト構造に適用可能であり、肉牛、豚、鶏などの他の家畜の飼料配合最適化問題にも応用できます。さらに、この手法は畜産業以外の分野にも適用可能です。例えば、製造業における原材料の配合最適化、農業分野での作物の肥料配合、食品産業におけるレシピの最適化などにも活用できます。