ksk00's picture
v3: availability-aware contingency policy (all suppliers A-E, state-sensitive)
e2ef6a7 verified
Raw
History Blame Contribute Delete
3.78 kB
"""Hugging Face Space โ€” Gradio ๋ฐ๋ชจ (v3, ๊ฐ€์šฉ์„ฑ ์ธ์ง€ ์ปจํ‹ด์ „์‹œ ์ •์ฑ…).
์žฌ๊ณ  + ๋‹น์ผ ์—…์ฒด ๊ฐ€์šฉ์„ฑ์„ ์ž…๋ ฅํ•˜๋ฉด RL ์—์ด์ „ํŠธ๊ฐ€ ์ƒํ™ฉ๋ณ„ ์ตœ์  ๋ฐœ์ฃผ๋ฅผ ์ถ”์ฒœํ•œ๋‹ค.
๊ฐ€์šฉ์„ฑ์„ ๋ฐ”๊พธ๋ฉด ์ถ”์ฒœ ์—…์ฒด๊ฐ€ ๋ฐ”๋€Œ๋Š” ์ปจํ‹ด์ „์‹œ ์ •์ฑ…์„ ์ฒดํ—˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
"""
import gradio as gr
from model import CONFIG, SUPPLIERS, demand_factors, load_model, recommend
MODEL_PATH = "best_model_v3.pt"
model = load_model(MODEL_PATH)
TAU_MAX = CONFIG["tau_max"]
SUP_NAMES = ["A", "B", "C", "D", "E"]
def predict(on_hand, pipeline_str, day_of_year, avail_a, avail_b, avail_c, avail_d, avail_e):
try:
pipeline = [float(x.strip()) for x in pipeline_str.split(",") if x.strip() != ""]
except ValueError:
return "โš ๏ธ ํŒŒ์ดํ”„๋ผ์ธ์€ ์ˆซ์ž ์ฝค๋งˆ๊ตฌ๋ถ„ (์˜ˆ: 0,0,0,0,0,0,0)"
if len(pipeline) != TAU_MAX:
return f"โš ๏ธ ํŒŒ์ดํ”„๋ผ์ธ์€ {TAU_MAX}๊ฐœ ๊ฐ’ ํ•„์š” (๋ฐ›์Œ {len(pipeline)}๊ฐœ)"
available = [avail_a, avail_b, avail_c, avail_d, avail_e]
idx, name, qty = recommend(model, float(on_hand), pipeline, int(day_of_year), available)
df = demand_factors(int(day_of_year))
avail_str = ", ".join(n for n, a in zip(SUP_NAMES, available) if a) or "(์ „๋ถ€ ํ’ˆ์ ˆ)"
if idx == 0:
head = "### ์ถ”์ฒœ: **๋ฐœ์ฃผ ์•ˆ ํ•จ (None)**\n๊ฐ€์šฉ ์—…์ฒด ์ค‘ ๋ฐœ์ฃผ ์ด๋“์ด ์—†๊ฑฐ๋‚˜ ์žฌ๊ณ  ์ถฉ๋ถ„."
body = ""
else:
info = SUPPLIERS[idx]
head = f"### ์ถ”์ฒœ ๊ณต๊ธ‰์—…์ฒด: **{name}** ยท ์ฃผ๋ฌธ๋Ÿ‰ **{qty}**"
body = (f"\n- ๋ฆฌ๋“œํƒ€์ž„ {info['tau']}์ผ ยท ๋‹จ๊ฐ€ {info['P']} ยท MOQ {info['MOQ']}")
return (
f"{head}{body}\n\n"
f"> ๊ฐ€์šฉ ์—…์ฒด: **{avail_str}**\n"
f"> ๊ธฐ๋Œ€์ˆ˜์š”(์˜ค๋Š˜/3์ผ/7์ผ): {df[0]:.2f} / {df[1]:.2f} / {df[2]:.2f}\n"
f"> ์žฌ๊ณ  {on_hand}, ์—ฐ์ค‘์ผ {day_of_year}"
)
with gr.Blocks(title="Dynamic Supplier Selection v3") as demo:
gr.Markdown(
"# ๐Ÿ“ฆ ๋™์  ๊ณต๊ธ‰์—…์ฒด ์„ ์ • RL ์—์ด์ „ํŠธ (v3)\n"
"์žฌ๊ณ  + **๋‹น์ผ ์—…์ฒด ๊ฐ€์šฉ์„ฑ**์„ ์ž…๋ ฅํ•˜๋ฉด ์ƒํ™ฉ๋ณ„ ์ตœ์  ๋ฐœ์ฃผ๋ฅผ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. "
"๊ฐ€์šฉ์„ฑ ์ฒดํฌ๋ฅผ ๋ฐ”๊ฟ”๋ณด์„ธ์š” โ€” 1์ˆœ์œ„ ์—…์ฒด๊ฐ€ ํ’ˆ์ ˆ์ด๋ฉด **์ฐจ์„ ์ฑ…์œผ๋กœ ์ž๋™ ํด๋ฐฑ**ํ•˜๋Š” "
"์ปจํ‹ด์ „์‹œ ์ •์ฑ…์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."
)
with gr.Row():
with gr.Column():
on_hand = gr.Number(value=1000, label="ํ˜„์žฌ ๋ณด์œ  ์žฌ๊ณ  (on_hand)")
pipeline = gr.Textbox(value="0,0,0,0,0,0,0",
label=f"ํŒŒ์ดํ”„๋ผ์ธ (ํ–ฅํ›„ 1~{TAU_MAX}์ผ ์ž…๊ณ ์˜ˆ์ •, ์ฝค๋งˆ {TAU_MAX}๊ฐœ)")
day = gr.Slider(0, 364, value=150, step=1, label="์—ฐ์ค‘ ์ผ์ž (๊ณ„์ ˆ์„ฑ)")
gr.Markdown("**๋‹น์ผ ์—…์ฒด ๊ฐ€์šฉ์„ฑ** (์ฒดํฌ=์ฃผ๋ฌธ ๊ฐ€๋Šฅ)")
with gr.Row():
ca = gr.Checkbox(value=True, label="A (๋ฆฌ๋“œ7ยท์ €๊ฐ€)")
cb = gr.Checkbox(value=True, label="B (๋ฆฌ๋“œ5)")
cc = gr.Checkbox(value=True, label="C (๋ฆฌ๋“œ3)")
cd = gr.Checkbox(value=True, label="D (๋ฆฌ๋“œ1)")
ce = gr.Checkbox(value=True, label="E (์ฆ‰์‹œยท๊ณ ๊ฐ€)")
btn = gr.Button("๋ฐœ์ฃผ ์ถ”์ฒœ ๋ฐ›๊ธฐ", variant="primary")
with gr.Column():
out = gr.Markdown()
inputs = [on_hand, pipeline, day, ca, cb, cc, cd, ce]
btn.click(predict, inputs=inputs, outputs=out)
gr.Examples(
examples=[
[1000, "0,0,0,0,0,0,0", 150, True, True, True, True, True],
[1000, "0,0,0,0,0,0,0", 150, False, True, True, True, True],
[200, "0,0,0,0,0,0,0", 100, True, True, True, True, True],
[1800, "0,0,0,0,0,0,0", 100, True, True, True, True, True],
],
inputs=inputs,
)
if __name__ == "__main__":
demo.launch()