業界別最適化Example集: 視聴者満足度最大化問題 (放送)
nAG数値計算ライブラリ > 業界別最適化Example集 > 視聴者満足度最大化問題 (放送)

Keyword: 放送, 最適化, 番組スケジューリング, セットパッキング問題, MILP

放送分野の最適化問題:視聴者満足度最大化問題

問題の概要

番組

番組のスケジューリングは、視聴者満足度を最大化するために重要な役割を果たします。この問題では、番組の放送時間帯の重複を避け、視聴者満足度の合計を最大化するような番組の組み合わせを見つけることを目的とします。最適化アルゴリズムを用いることで、効果的な番組編成を実現できます。

視聴者満足度最大化問題(具体例)

あるテレビ局が1日の番組スケジュールを決める際、以下の5つの番組候補があります。各番組は特定のジャンルと放送時間帯を持ち、それぞれが視聴者満足度を示す点数が割り当てられています。例えば、ドラマの番組Aは19:00から20:00まで放送され、満足度は80点です。

テレビ局の目標は、番組が時間帯で重ならないようにしながら、最も視聴者の満足度を高める番組の組み合わせを選ぶことです。このために、番組の選択に関する以下の情報が利用されます。

番組 ジャンル 放送時間帯 視聴者満足度
A ドラマ 19:00-20:00 80
B バラエティ 19:30-20:30 75
C ニュース 20:00-21:00 60
D スポーツ 20:30-22:00 90
E 映画 21:00-23:00 85

この問題を解くことによって、視聴者が最も楽しめる番組ラインナップを作成することができます。

問題の定式化

この最適化問題は、番組を選択するかどうかを示す決定変数として xi を用います。xi が1であれば番組を選択し、0であれば選択しないとされます。目的関数は選ばれた番組の視聴者満足度の合計を最大化することです。以下に詳細を示します。

パラメータ

パラメータ 説明
n 番組候補の数 5
wi 番組 i の視聴者満足度 w1=80, w2=75, w3=60, w4=90, w5=85
aij 番組 i と番組 j の放送時間帯が重複する場合は1,そうでない場合は0 a12=a21=1, a23=a32=1, a34=a43=1, a45=a54=1, その他は0

決定変数

変数 説明 範囲
xi 番組 i を選択する場合は1,そうでない場合は0 xi{0,1}

目的関数

目的
視聴者満足度の最大化 maximizei=1nwixi

目的関数は、選択された番組の視聴者満足度の合計を最大化することです。これにより、視聴者にとって最も魅力的な番組の組み合わせを提供できます。

制約条件

制約 説明
放送時間帯の重複回避 i=1naijxi1,j 選択された番組の放送時間帯が重複しないようにする
変数の二値制約 xi{0,1},i 番組は選択されるか選択されないかのどちらかである

放送時間帯の重複回避制約により、視聴者が同じ時間帯に複数の番組を見ることができなくなるのを防ぎます。また、変数の二値制約により、番組は選択されるか選択されないかのどちらかであることを保証します。

コード例

以下に、この混合整数線形計画問題を nAG Library for Python の MILP 問題専用ソルバー関数 handle_solve_milp を用いて解くコード例を示します。

今回の問題はバイナリ制約を含む混合整数線形計画問題であるため、handle_solve_milp のような汎用的な MILP ソルバーを選択しました。

from naginterfaces.library import opt
from naginterfaces.library import mip

# 番組データ
programs = [
    {'name': 'A', 'genre': 'ドラマ', 'start': 19, 'end': 20, 'satisfaction': 80},
    {'name': 'B', 'genre': 'バラエティ', 'start': 19.5, 'end': 20.5, 'satisfaction': 75},
    {'name': 'C', 'genre': 'ニュース', 'start': 20, 'end': 21, 'satisfaction': 60},
    {'name': 'D', 'genre': 'スポーツ', 'start': 20.5, 'end': 22, 'satisfaction': 90},
    {'name': 'E', 'genre': '映画', 'start': 21, 'end': 23, 'satisfaction': 85}
]

n_programs = len(programs)

# 重複する番組のペアを計算
overlapping_pairs = []
for i in range(n_programs):
    for j in range(i+1, n_programs):
        if programs[i]['start'] < programs[j]['end'] and programs[j]['start'] < programs[i]['end']:
            overlapping_pairs.append((i, j))

# ハンドルの初期化
handle = opt.handle_init(nvar=n_programs)

# 目的関数の設定(視聴者満足度の最大化)
opt.handle_set_linobj(handle, [p['satisfaction'] for p in programs])

# 変数の範囲を設定(0 or 1)
opt.handle_set_simplebounds(handle, bl=[0]*n_programs, bu=[1]*n_programs)

# 変数の性質を設定(バイナリ変数)
opt.handle_set_property(handle, ptype='BINARY', idx=list(range(1, n_programs+1)))

# 放送時間帯の重複を避けるための制約を設定
for pair in overlapping_pairs:
    i, j = pair
    bl = [0] # 下限値は0
    bu = [1] # 上限値は1
    irowb = [1, 1] # 制約行番号
    icolb = [i+1, j+1] # 制約列番号
    opt.handle_set_linconstr(handle, bl=bl, bu=bu, irowb=irowb, icolb=icolb, b=[1, 1])

opt.handle_opt_set(handle, 'Task = Maximize')
opt.handle_opt_set(handle, 'Print Level = 0')

# 問題を解く
x = mip.handle_solve_milp(handle)[0]

# 結果を出力
print("選択された番組:", [programs[i]['name'] for i in range(n_programs) if x[i] > 0.5])
print("合計視聴者満足度:", sum(x[i] * programs[i]['satisfaction'] for i in range(n_programs)))

# ハンドルを解放
opt.handle_free(handle)

結果例

上記のコードを実行すると、以下のような出力が得られます。

選択された番組: ['A', 'C', 'E']
合計視聴者満足度: 225.0

最適解は、番組A、C、Eを選択することであり、合計視聴者満足度は225となります。この結果から、放送時間帯の重複を避けつつ、視聴者満足度を最大化する番組の組み合わせが得られたことがわかります。

まとめ

本問題では、混合整数線形計画法を用いて、放送時間帯の重複を避けつつ視聴者満足度を最大化する番組スケジューリングを行いました。nAG Library for Pythonのhandle_solve_milp関数を使用することで、効率的に最適解を求めることができました。

この手法は、制約条件の追加や目的関数の変更により、広告収入最大化などの他の目的にも応用可能です。


関連情報
© 日本ニューメリカルアルゴリズムズグループ株式会社 2024
Privacy Policy  /  Trademarks