ピザの味を最大限に引き出すために

Methods to Maximize the Deliciousness of Pizza)

多くの人々はピザに愛着を持っており、辛さやヴィーガン、ベジタリアン、ペスカタリアン、肉食、マキャベリアン、あるいはクラシックなチーズ好きなど、さまざまな好みがあります。

ピザ店オーナーが直面する課題は、ビジネスを運営する複雑さと顧客の多様な好みに対応することです。このジレンマに対処するために、データサイエンティスト(DS)が雇われました。幸運なことに、DSはピザが大好きで、それが仕事の説明として明示されていました。

DSのタスクは解決策を考案することであり、以下に示すのがその結果です。下のグラフは、20種類の異なるピザの具材について、50人の顧客の好みを示しています。データは匿名化されており、ピザにパイナップルやニンニクを好むかどうかなど、顧客の好みは機密となっています。

例えば、顧客0はペパロニ、パイナップル、ニンニクを好み、リコッタチーズ、ベーコン、玉ねぎは嫌いです。この重要な顧客は他の具材には無関心です。そのため、メニューが好みの具材(緑色)を取り入れ、嫌いな具材(赤色)を除外していれば、顧客の満足度は維持されます。

顧客の好みがデータサイエンティスト(DS)によって把握されたことで、次のステップでは問題を数学的に定式化する方法を決定する必要があります。この段階が意思決定の鍵となります。

目的:喜んでいる顧客の数を最大化して顧客の満足度を高める。

制約条件:すべての要件を満たし、厄介な顧客対応は酸っぱい味を残しながらも甘さを要求する苦い果実と同様であることを認識する。

変数:具材の選択(Xe)と満足した顧客(Uc)を示すバイナリ変数を使用する。

{(0, 'L'): {2, 10, 13, 18}, (0, 'D'): {5, 8, 16}, (1, 'L'): set(), (1, 'D'): set(), (2, 'L'): set(), (2, 'D'): {0, 2, 4, 18}, (3, 'L'): {12, 13, 14}, (3, 'D'): set(), (4, 'L'): {15}, (4, 'D'): {4, 5, 6, 18}, (5, 'L'): {0, 8}, (5, 'D'): {6}, (6, 'L'): {0, 13, 14, 17}, (6, 'D'): {4, 7, 10}, (7, 'L'): {1, 6, 10, 14}, (7, 'D'): {15}, (8, 'L'): {3, 7, 18}, (8, 'D'): {4, 5, 9, 15}, (9, 'L'): {10, 15}, (9, 'D'): {8, 14, 18, 19}, (10, 'L'): set(), (10, 'D'): {7, 14, 16}, (11, 'L'): {1, 2, 12}, (11, 'D'): {3, 10}, (12, 'L'): {5, 10, 13}, (12, 'D'): {19}, (13, 'L'): {1, 8, 14, 16}, (13, 'D'): {4, 12}, (14, 'L'): {0, 10, 12}, (14, 'D'): set(), (15, 'L'): {4}, (15, 'D'): {11}, (16, 'L'): set(), (16, 'D'): {3, 8, 10, 17}, (17, 'L'): {0, 11, 17, 18}, (17, 'D'): {6, 19}, (18, 'L'): {17}, (18, 'D'): {9, 11, 19}, (19, 'L'): {4, 7, 11}, (19, 'D'): set(), (20, 'L'): {5, 8, 15, 16}, (20, 'D'): {2, 11}, (21, 'L'): set(), (21, 'D'): {0, 6, 10, 13}, (22, 'L'): {2, 5, 7, 17}, (22, 'D'): {1, 3, 18}, (23, 'L'): {3, 13}, (23, 'D'): {4, 8, 12}, (24, 'L'): {8}, (24, 'D'): {3, 5, 17, 19}, (25, 'L'): {0, 7, 9, 10}, (25, 'D'): {2, 6, 19}, (26, 'L'): {10, 18}, (26, 'D'): {3, 4, 7}, (27, 'L'): {3, 6}, (27, 'D'): {7, 9, 16}, (28, 'L'): {7, 17}, (28, 'D'): set(), (29, 'L'): set(), (29, 'D'): {4, 6}, (30, 'L'): set(), (30, 'D'): {0, 4, 5, 19}, (31, 'L'): {5, 8, 18}, (31, 'D'): {0, 12, 13}, (32, 'L'): {8}, (32, 'D'): {0, 7}, (33, 'L'): set(), (33, 'D'): {0, 2, 12}, (34, 'L'): set(), (34, 'D'): {3, 15}, (35, 'L'): set(), (35, 'D'): set(), (36, 'L'): {7}, (36, 'D'): {0, 19}, (37, 'L'): {6}, (37, 'D'): {5, 13, 15, 19}, (38, 'L'): {7, 9, 16, 18}, (38, 'D'): {3}, (39, 'L'): {10, 13, 17}, (39, 'D'): {15}, (40, 'L'): {9, 15}, (40, 'D'): {8, 10, 18, 19}, (41, 'L'): {0, 5}, (41, 'D'): {14, 16}, (42, 'L'): {4, 13}, (42, 'D'): set(), (43, 'L'): {4, 8, 16}, (43, 'D'): {6, 7, 10}, (44, 'L'): {0, 12}, (44, 'D'): {3, 5, 8, 9}, (45, 'L'): {2, 10}, (45, 'D'): set(), (46, 'L'): {2, 5, 9, 12}, (46, 'D'): set(), (47, 'L'): set(), (47, 'D'): set(), (48, 'L'): {4, 7, 13}, (48, 'D'): {1}, (49, 'L'): {0, 15}, (49, 'D'): {2, 4, 12, 13}}

Pythonのコード

import networkx as nximport matplotlib.pyplot as pltpizza_ingredients = [    'モッツァレラチーズ',    'トマトソース',    'ペパロニ',    'マッシュルーム',    'ピーマン',    '玉ねぎ',    '黒オリーブ',    'ソーセージ',    'ベーコン',    'ハム',    'パイナップル',    'ハラペーニョ',    '新鮮なバジル',    'にんにく',    'オリーブオイル',    'パルメザンチーズ',    'リコッタチーズ',    'ほうれん草',    'チェリートマト',    'アンチョビ']plt.figure(figsize=(12,6))for c in customers:  X= [c for e in elements]  Y= [e for e in elements]  plt.scatter(X,Y, c='grey', s=20, alpha=0.4)      x= [c for e in data[c,'L'] ]  y= [e for e in data[c,'L'] ]  plt.scatter(x,y, c='g', s=50)  x= [c for e in data[c,'D'] ]  y= [e for e in data[c,'D'] ]  plt.scatter(x,y, c='r', s=50)  plt.xticks(list(customers),rotation=90, fontweight='bold')plt.yticks(list(elements), pizza_ingredients, fontweight='bold')plt.ylabel('材料', fontweight='bold')plt.xlabel('顧客', fontweight='bold')plt.tight_layout()fname = 'base_pizza.png'plt.savefig(fname)# ファイルをダウンロードするfiles.download(fname)plt.show()

%pip install ortoolsfrom ortools.sat.python import cp_modeldef main():    model = cp_model.CpModel()    X = {e:model.NewBoolVar(f"x_{e}") for e in elements}    Sc = {c:model.NewBoolVar(f"S_{c}") for c in customers}    for c,v in Sc.items():      for e in data[c,'L']:        model.Add(v<= X[e])      for e in data[c,'D']:        model.Add(v<= 1-X[e])        expressions = [v for s,v in Sc.items() ]    model.Maximize( cp_model.LinearExpr.Sum(expressions))    solver = cp_model.CpSolver()    status = solver.Solve(model)

シミュレーション結果:

HAMを含む選択された材料は、横のラインで示され、満足した顧客は縦のゴールデンラインで表されます。例えば、簡単な顧客である顧客1は特定の好みや嫌いな材料はありませんが、顧客28は2つの好きな材料(緑)と嫌いな材料(赤)はありません。

全体の目的関数の合計値は17です。Pythonのコードに興味がある場合は、GitHubリポジトリで見つけることができます。LinkedInではリンク付きの投稿が制限されるため、コメントセクションで見つけてください。すべてのリンクは等しく、しかし一部はより等しいです。

嫌いな材料を完全に無視する:

嫌いな材料の嫌悪感を無視して、許可される材料の数を10に制限すると、結果は次のようになります:

満足した顧客は28人です。

一つの嫌いな材料を許容する:

許可される材料の数を10に制限すると、結果は次のようになります:

満足した顧客は21人です。

好きな材料の数が嫌いな材料よりも多い場合に許容する:

許可される材料の数を10に制限すると、結果は次のようになります:

27満足のお客様。

これは単純化されたシナリオであることを理解しています。実際のピザ店では、さまざまな考慮事項や制約が関与するため、座ってリラックスしてピザをお楽しみください。

この問題は、google-hash-code-2022-practice-problemに触発されました。

Github: https://github.com/OptimizationExpert/Pyomo

お楽しみください!

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

AI研究

Google DeepMindの研究者がSynJaxを紹介:JAX構造化確率分布のためのディープラーニングライブラリ

データは、その構成要素がどのように組み合わさって全体を形成するかを説明するさまざまな領域で構造を持っていると見なすこ...

機械学習

このAI論文は、「Vary」という新しいアプローチを明らかにしています:高度な多言語認識タスクのための大規模なビジョン言語モデルの視覚語彙を拡張するためのアプローチ

大視覚言語モデル(LVLM)は、コンピュータビジョンと自然言語処理を組み合わせて、視覚的なコンテンツのテキストの説明を生...

AI研究

Amazonの研究者たちが提案するディープラーニングのトレーニングのためのコンパイラには、3つの主な特徴があります- Syncfreeオプティマイザ、コンパイラキャッシュ、およびマルチスレッド実行

機械学習の最大の課題の1つは、ニューラルネットワークを効率的にトレーニング及び使用することです。トランスフォーマーモデ...

AIニュース

「OpenAIのWebクローラーとFTCのミスステップ」

「OpenAIは、デフォルトでオプトイン型のクローラーを起動してインターネットをスクレイピングする一方で、FTCは不明瞭な消費...

機械学習

「MATLABとAmazon SageMakerによる機械学習」

この投稿はMathWorksのBrad Duncan、Rachel Johnson、Richard Alcockとの共同執筆ですMATLABはデータ処理、並列コンピューテ...

AIニュース

サイバー犯罪の推進者' (Saibā hanzai no suishinsha)

イニシャルアクセスブローカーは、無許可のアクセスを販売します (Inisharu akusesu burōkā wa, mukyoka no akusesu o hanbai...