æ°çæé©åããããã¯ãã«çµã¿è¾¼ãã§ããå ´åãã¯ã©ã¹ã¨ãã¦é¨ååãã¦ããã¨ãåå©ç¨æ§ãä¿å®æ§ãé«ã¾ã£ããããã
æ°çæé©åã®ã¯ã©ã¹è¨è¨ã«é¢ãã¦ã¯ãæ¸ç±ãPythonã§ã¯ãããæ°çæé©åãã®èè ã§ãã岩永ããã次ã®ãããªè¨äºãæ¸ããã¦ããï¼
ãã®è¨äºã¯ã¯ã©ã¹ã£ã¦ã©ãå®ç¾©ãããããã®ãåãããªãã£ã¦äººã«ã¯æéãä¸ãã¦ãããã®ã§ã¨ã¦ãããã¨æãã Python使ã£ã¦ã人ã£ã¦èªåã§ã¯ã©ã¹ãæ¸ãããããã«ã³ã¼ãæ¸ãã¦ã人ããã£ããå¤ãã®ã§ã
ãã ãã¨ããããã®ä¸æ©ã¨ãã¦ã¯ãããã©ãã³ã¼ããããå ç¢ã«ããã¨ãã観ç¹ã§ã¯ã¡ãã£ã¨åé¡ãå¤ãã£ããã ãã®ãããã¯ãªãã¸ã§ã¯ãæåã«ã¤ãã¦ã®çµé¨å¤ãè¦æ±ããããããã
ã¨ãããã¨ã§ãããããã¯ã©ã¹è¨è¨ã«ã¤ãã¦æ¸ãã¦ã¿ããã
ããã¯æ°çæé©å Advent Calendar 2024ã®5æ¥ç®ã®è¨äºã§ãã
åè¿°ã®ã¯ã©ã¹è¨è¨ã®åé¡ç¹
ã¾ããåè¿°ã®ã¯ã©ã¹è¨è¨ã®åé¡ç¹ãå ·ä½çã«ç¤ºãã¦ããããã
- å¼æ°ã®åããã¼ã¿æ§é ãåãããªã
- å¼æ°ã®å¦¥å½ãªå¤ãåãããªããä¸é©åãªå¤ã渡ãã¦ãã¾ã
- ãªãã¸ã§ã¯ãã®ç¶æ ãæ°ã«ããã¡ã½ããå¼ã³åºããå¿ è¦
- ãªãã¸ã§ã¯ãã®ãã¼ã¿ãç ´å£ã§ãã¦ãã¾ã
å¼æ°ã®åããã¼ã¿æ§é ãåãããªã
ã¯ã©ã¹ã使ãã¨ãã«è¦ãã®ããã¡ã½ããã®ã·ã°ããã£ï¼ã©ããªå¼æ°ã渡ããï¼ã ã³ã³ã¹ãã©ã¯ã¿ã®ã·ã°ããã£ãè¦ãã¨ã次ã®ããã«ãªã£ã¦ããï¼
class ProdPlan: def __init__(self, P, M, m2s, p2g, pm2r): ...
ãã ãããã ãè¦ã¦ãä½ã®ãã¼ã¿ã渡ãã°ããã®ãããã£ã±ãåãããªãã å®è£ ã追ã£ã¦ãã£ãããå¼ã³åºãä¾ãè¦ã¦ããå¿ è¦ãããã ããã¯ãã£ãã大å¤ã
対çã¨ãã¦ãPythonã§ã¯åãã³ããã¤ãããdocstringã§èª¬æããããã§ããï¼
class ProdPlan: def __init__( self, P: list[str], M: list[str], m2s: dict[str, int], p2g: dict[str, int], pm2r: dict[tuple[str, str], int], ) -> None: """ Parameters ---------- P : list[str] 製åã®ä¸è¦§ M : list[str] åæã®ä¸è¦§ m2s : dict[str, int] å¨åº«éï¼ãã¼ã¯åæï¼ p2g : dict[str, int] å©å¾ï¼ãã¼ã¯è£½åï¼ pm2r : dict[tuple[str, str], int] å¿ è¦éï¼ãã¼ã¯è£½åã¨åæã®ãã¢ï¼ """ ...
åãã³ããdocstringãããã ãã§ã使ãããããã ãã¶å¤ããã®ãåãããã¨æãã æ£ç´ãæ¸ãã®ã¯ããªãé¢åã ãã©ããããã¯ãã§ä½¿ãå ´åã¯å¿ é ã«è¿ãã
å¼æ°ã®å¦¥å½ãªå¤ãåãããªããä¸é©åãªå¤ã渡ãã¦ãã¾ã
ãã ãããã§ãã¾ã ä¸ååã§ãã¨ããã®ããªã¹ããè¾æ¸ã¨ãã£ããã¼ã¿æ§é ã§ã¯å¤ã«å¯¾ãããç¸ããããªããããå¼æ°ã¨ãã¦å¦¥å½ãªå¤ãåãããªãã£ãããããããä¸é©åãªå¤ãç°¡åã«æ¸¡ãã¦ãã¾ãããã
ãã¨ãã°ã次ã®ãããªã³ã¼ããæ¸ãã¦ãã¾ã£ããããï¼
P = ["p1", "p2", "p3", "p3"] # ååã®è£½åããã M = ["m1", "p2", "m3"] # m2ãp2ã¨ã¿ã¤ãï¼åæã®ãã¼ã¨è£½åã®ãã¼ã§åºå¥ãã¤ããªããªãï¼ m2s = {"m1": 35, "m2": -10} # m2ã®å¨åº«ãè² ãm3ã®å¨åº«ãæªå®ç¾© p2g = {"p1": 3, "p2": 4, "p3": 4, "p4": -5, "m1": 10} # p4ã®å©å¾ãè² ããã¼ã«m1ãå«ã¾ãã pm2r = { ("p1", "m1"): 2, ("p1", "m2"): 0, # PÃMã®ç¶²ç¾ ãã§ãã¦ãªã ("hoge", "huga"): -2, # å¤ãªãã¼ããããå¿ è¦éãè² } prod_plan = ProdPlan(P, M, m2s, p2g, pm2r)
ä¸è¨ã ã¨åãã§ãã¯ã§ã¨ã©ã¼ã¯æ¤åºãããªãããå®è¡æã«ãã¨ã©ã¼ã¯åºã¦ããªãã
prod_plan.modeling()
ãprod_plan.solve()
ãå¼ã³åºããã¨ãã«ãéããããã°ã¨ã©ã¼ã«ãªãããã
ãã ãææªã¨ã©ã¼ãåºãã«ãçãããããããªã£ã¦ããã¨ã«æ°ã¥ããªãã¾ã¾ä½¿ã£ã¦ãã¾ãå¯è½æ§ãããï¼ã¨ã©ã¼ãåºãã®ãå«ãã人ãå¤ããã©ãåé¡ãããã®ã«ã¨ã©ã¼ãåºãªãã¨ããã®ã¯ãããªãæ害ï¼ã¬ã³ãããã®ã«æ¤æ»ã§å¼ã£ããããªããããªãã®ãªã®ã§ï¼ã
ãªãã¸ã§ã¯ãã®ç¶æ ãæ°ã«ããã¡ã½ããå¼ã³åºããå¿ è¦
ãã®ã¯ã©ã¹ã¯ãªãã¸ã§ã¯ãã®ç¶æ ãæ°ã«ãã¦ã¡ã½ããå¼ã³åºããããªãã¨ãããªãã¨ããã®ããã£ããé£ç¹ã
ãã¨ãã°ããã®ãªãã¸ã§ã¯ããä½ãããã®é¢æ°ã§å¼æ°ã¨ãã¦åãåã£ãã¨ããã æé©åã®çµæãç¥ãããã¨ãã¦ãã©ããããããã ãããï¼
# æé©åã®çµæã®è¡¨ç¤º def print_result(prod_plan: ProdPlan) -> None: # prod_planã«å¯¾ãã¦ãä½ãããã°ããï¼ ...
çããç¥ããããã ããprod_plan.x
ãè¦ãã°ãããã§ããï¼ã£ã¦æããããããªããã©ãå¿
ãããããã¨ã¯éããªãã
ã ã£ã¦ãmodeling()
ãå¼ã³åºãã¦ãªãã¨x
ã¯None
ã ããsolve()
ãå¼ãã§ãªãã¨x
ã¯æé©è§£ã«ãªã£ã¦ãªãããã
使ãå´ãç¶æ
ãæ°ã«ããªããå¿
è¦ãªã¡ã½ãããå¼ã³åºãã¦ããå¿
è¦ãããã
# æé©åã®çµæã®è¡¨ç¤º def print_result(prod_plan: ProdPlan) -> None: if prod_plan.x is None: prod_plan.modeling() if prod_plan.status is None: prod_plan.solve() print({p: prod_plan.x[p].value() for p in prod_plan.P})
ä¸å¿ãmodeling()
ã¨solve()
ã常ã«å¼ã³åºãããã«ããã°ãç¶æ
ã®ç¢ºèªã¯ä¸è¦ã«ãªããã©ããã§ã«è§£ãã¦ãå ´åã¯ç¡é§ã«è¨ç®ãã¦ããã¨ã«ãªãããããã®å¼æ°ã§ã¯è§£ãããã¨ã®ç¶æ
ã®ãªãã¸ã§ã¯ãã常ã«æ¸¡ãããã¨åã決ãã¦ããã°ãããã£ããã§ãã¯ã¯ä¸è¦ã«ãªããã©ããã®ç´æãç¥ã£ã¦ãç¥ãããç ´ã£ã¦ãã¾ã£ã¦ãã°ãå¼ãèµ·ããã¨ããã®ããããã話ã
ããã¡ã½ãããå¼ã³åºãæ¸ã¿ãã©ãããªãã¦ãããã«è³ããã¹ãå
¨é¨ãã§ãã¯ãã¦ãããªãã¨ãæãæ¼ãã¯æ®éã«çºçãããã
ãªãã¸ã§ã¯ãã®ãã¼ã¿ãç ´å£ã§ãã¦ãã¾ã
ãã®ã¯ã©ã¹è¨è¨ã¯ãã¼ã¿æ§é ã丸è¦ããªã®ã§ããªãã¸ã§ã¯ãã®ãã¼ã¿ãç°¡åã«ç ´å£ã§ãã¦ãã¾ãåé¡ãããã
ãã¨ãã°ãããªæãï¼
# 以ä¸ã®ããã«ãããã¨ã©ã¼ãåºãªããªã£ãã®ã§ã¨ã·ï¼ prod_plan.x = pulp.LpVariable.dicts("x", prod_plan.P) prod_plan.status = pulp.LpStatusOptimal print_result(prod_plan)
ãããªã¢ããªãã¨ãããããªã¨æããããããªããã©ããã£ãã¨ãã¦ãã¨ã©ã¼ã¯åºã¦ããªãã®ã§ããã£ã¦ãªããã¨ã確èªããã«ã¯ã½ã¼ã¹ã³ã¼ããå ¨é¨ãã§ãã¯ããªãã¨åãããªããããã
åé¡ã¸ã®å¯¾å¿ç
ä¸è¨ã®ãããªåé¡ãé²ãã«ã¯ã以ä¸ã®ãããªãã¨ããã£ã¦ãããã¨ããï¼
- åãã³ããdocstringãæ¸ãï¼è¨åæ¸ã¿ï¼
- ç°ãªããã®ã«ã¯ç°ãªãåã®ã¯ã©ã¹ãç¨æãã
- ä¸é©åãªãã¼ã¿ãåå¨ã§ããªãããã«ãã
- ã§ãããã¨ã ããã¡ã½ããã«ãã
ç°ãªããã®ã«ã¯ç°ãªãåã®ã¯ã©ã¹ãç¨æãã
製åãåæã¯ç°ãªããã®ãªã®ã§ãããããæ··ãã£ã¦ãã¾ãã®ã¯ãããªãã ãã©ãåã«æååã§èå¥ãè¡ãªã£ã¦ããã®ã ã¨ãåã¨ãã¦ã¯åããªã®ã§åºå¥ãã¤ãããæ··ãã£ã¦ãã¾ãå¯è½æ§ãããã
ããããã¨ãã«ã¯ç°ãªãåãç¨æãã¦ããã¨ããã¦ãããããã¨æ··ãã£ã¦ãã¾ãã®ãåãã§ãã¯ã§é²ããããã«ãªãï¼
from dataclasses import dataclass @dataclass(frozen=True) class Product: """製å""" name: str @dataclass(frozen=True) class Material: """åæ""" name: str products: list[Product] = [ Product("p1"), Product("p2"), Product("p3") ] materials: list[Material] = [ Product("m1"), Material("m2") # ããã¯åãã§ãã¯ããã¨ã¨ã©ã¼ãæ¤åºããã ]
ã¾ãããããã¦ããã¨ãè¾æ¸ã§ãã¼ã«ãªãè¦ç´ ããªããªã®ããåããããããªã£ããï¼
# å ã ã¯ä»¥ä¸ã ã£ãï¼ # ãã¼ã¨å¤ãä½ãæå³ãã¦ãããããåãããªã m2s = {"m1": 35, "m2": 22, "m3": 27} # 以ä¸ã®ããã«ããã¨åããããã stocks: dict[Material, int] = { Material("m1"): 35, Material("m2"): 22, Material("m3"): 27, }
ä¸é©åãªãã¼ã¿ãåå¨ã§ããªãããã«ãã
æ±ã£ã¦ããã¼ã¿ã«ã¯ãããã¤ãå¶ç´ããã£ããããï¼
- 製åã®éåã«ååã®è£½åãå«ã¾ããã®ã¯NG
- åæã®éåã«ååã®åæãå«ã¾ããã®ã¯NG
- åæã®å¨åº«ã¯ååæã«å¯¾ãã¦å¤ãããã0以ä¸ã®å¤ãåã
- 製åã®å©å¾ã¯å製åã«å¯¾ãã¦å¤ãããã0以ä¸ã®å¤ãåã
- 製åã«å¯¾ããåæã®å¿ è¦éã¯ãå製åã¨ååæã®ãã¢ã«å¯¾ãã¦å¤ãããã0以ä¸ã®å¤ãã¨ã
ãããã£ãã®ã¯ãã¡ã¤ã³ç¥èã¨å¼ã°ãããã®ã§ãããããæ´ãåºããã³ã¼ãã¨ãã¦è¡¨ç¾ãã¦ãããã¨ããã¨ã«ãªã£ã¦ããã£ãããã ã£ãã®ï¼ãã¨ããã®ãé²ãããã ããã¦ããããã£ãå¶ç´ãç ´ãä¸é©åãªãã¼ã¿ãåå¨ã§ããªãããã«ãã¦ããã¨ãä¸é©åãªãã¼ã¿ãç´ãã¦æ°ã¥ããªããã¡ã«åé¡ãçºçãã¦ããã¨ããã®ãé²ããããã«ãªãã
å ·ä½çã«ã¯æ±ããã¼ã¿ãæ¦å¿µãã¯ã©ã¹ã¨ãã¦è¡¨ç¾ãã¦ãä¸é©åãªãªãã¸ã§ã¯ããä½ãããªãããã«ããã¨ããï¼ä¸é©åã«ãªãå ´åã¯ä¾å¤ãæããï¼ã
ãã¨ãã°ã製åã®ä¸è¦§ã®å®è£ ä¾ã¯ä»¥ä¸ï¼
class ProductList: """製åã®ä¸è¦§""" def __init__(self, items: list[Product]) -> None: """ Parameters ---------- items : list[Product] 製åã®ä¸è¦§ Raises ------ ValueError éè¤ãã製åããã£ãå ´å """ # éè¤ãã§ã㯠n_items = len(items) n_unique_items = len(set(items)) if n_items != n_unique_items: raise ValueError("製åãéè¤ãã¦ã¾ã") self.__items = list(items) @property def items(self) -> list[Product]: return list(self.__items) def __eq__(self, obj: object) -> bool: return ( isinstance(obj, ProductList) and (set(self.__items) == set(obj.items)) )
ãã¤ã³ãã¯ã³ã³ã¹ãã©ã¯ã¿ã§éè¤ãã§ãã¯ããã¦ããã¨ã ãããã£ã¦ãã¼ã¿ãä½ãã¨ãã«å¶ç´ãå®ããã¦ãããã®ãã§ãã¯ãå ¥ãã¦ããã¨ãå¶ç´ãå®ããã¦ãªãä¸é©åãªãã¼ã¿ã¯ããã°ã©ã å ã«åå¨ã§ããªããªãï¼
# 次ã®ã³ã¼ãã¯åãã§ãã¯ã§å¼¾ããã product_list = ProductList([Product("p1"), Material("m1")]) # 次ã®ã³ã¼ãã¯å®è¡æã«ValueErrorãåºã product_list = ProductList([Product("p1"), Product("p2"), Product("p1")])
ã¡ãªã¿ã«ã次ã®é
ç®ã¨ãé¢é£ãããã©ããã®ProuctList
ã«å«ã¾ãã製åã®ä¸è¦§ã¯ãåç
§ã¯ã§ãã¦ãå¤æ´ã¯ã§ããªãããã«ãªã£ã¦ããï¼
product_list = ProductList([...]) # åç §ã¯ã§ãã for product in product_list.items: print(product) # ä»£å ¥ã¯ã§ããªã product_list.items = [Product("p3"), Product("p4")] # ã¨ã©ã¼
ããã¯ãªãã¸ã§ã¯ãã®æã¤ãã¼ã¿ããã©ã¤ãã¼ãã«ãã¦å¤ããã¯ã¢ã¯ã»ã¹ã§ããªãããã«ããããããã£ã¨ãã¦åç §ã ãã§ããããã«ãã¦ãããã ãããããã¨ã§ãé©åã ã£ããã¼ã¿ãéä¸ã§ä¸é©åãªãã¼ã¿ã«å¤ãã£ã¦ãã¾ãã®ãé²ãã§ããã
製åã®å©å¾ã®å®è£ ä¾ã示ãã¦ããã¨ã以ä¸ï¼
class Gain: """製åã®å©å¾""" def __init__(self, gains: dict[Product, int]) -> None: """ Parameters ---------- gains : dict[Product, int] 製åã®å©å¾ å¤ã¯0以ä¸ã§ããã㨠Raises ------ ValueError å¤ã0æªæºã®å ´å """ for value in gains.values(): if value < 0: raise ValueError("å¤ã0æªæºã§ã") self.__gains = dict(gains) @property def product_list(self) -> ProductList: return ProductList(list(self.__gains.keys())) def for_product(self, product: Product) -> int: """ æå®ããã製åã«å¯¾ããå©å¾ãè¿ã Parameters ---------- product : Product 対象ã®è£½å Returns ------- int æå®ããã製åã«å¯¾ããå©å¾ Raises ------ ValueError æå®ããã製åã«å¯¾ããå¤ããªãå ´å """ if product not in self.__gains: raise ValueError(f"{product}ã«å¯¾ããå¤ãããã¾ãã") return self.__gains[product]
ã§ãããã¨ã ããã¡ã½ããã«ãã
ä¸è¨ã§ãã¼ã¿ãåç §ã¯ã§ãã¦ãå¤æ´ã¯ã§ããªãããã«ããã®ã¨åæ§ã§ãã§ãããã¨ã ããã¡ã½ããã¨ãã¦å ¬éããã¨ããã
ãã¨ãã°ãå
ã®è¨è¨ã ã¨ProdPlan
ãã§ãããã¨ã¯æ¬¡ã®ããã«ãªã£ã¦ããï¼
- åå±æ§ã®åç §ãå¤æ´
- ã¢ããªã³ã°ãã¦å é¨ç¶æ ãæ´æ°ãã
- ã¢ããªã³ã°ããåé¡ã解ãã¦å é¨ç¶æ ãæ´æ°ãã
ãã©ãããã¯å ¬éãããã§ãåè¿°ã®ããã«ç°¡åã«ãã¼ã¿ãå£ãã¦ãã¾ããã使ãå´ãç¶æ ãæèããå¿ è¦ããã£ã¦ä½¿ãã«ããã
å®éã«ã¯æ¬¡ã®ãã¨ãã§ããã°ååï¼
- åå±æ§ã®åç §
- åé¡ã解ãã¦è§£ãå¾ã
æ°ãã¤ãããã®ã¯ããã¢ããªã³ã°ãããã解ãæ±ãããã解ã®å¤ãå¾ããã¨ããã®ãåå¥ã®ã¡ã½ããã«ããªããã¨ã ãªããªããããããã ãããã¨ãããã¨ã¯æ®éããå¾ãªãããã ä¸æã«åãã¦ãã¾ãã¨ãå é¨ã®ç¶æ ã«æ°ãã¤ããªããå¿ è¦ãªã¡ã½ãããé ã«å©ãã¦ããå¿ è¦ãåºã¦ãã¾ãã å é¨çã«å¦çãåãã¦æ¸ãããå ´åã¯ããã©ã¤ãã¼ããªã¡ã½ããã¨ãã¦æ¸ãã¨ããã
å ·ä½çã«ã¯ã次ã®ãããªæãã«ãªãï¼
from typing import Optional class ProductionPlan: """çç£è¨ç»""" def __init__(self, plan: dict[Product, float]) -> None: # å¶ç´ã¨ãåæ§ã«è¡¨ç¾ãã ... # çç¥ class ProductionProblem: """çç£åé¡""" def __init__( self, product_list: ProductList, material_list: MaterialList, stock: Stock, gain: Gain, require: Require, ) -> None: # docstringçç¥ if stock.material_list != material_list: raise ValueError("å¨åº«ã®æ å ±ãä¸æ£ã§ã") if gain.product_list != product_list: raise ValueError("å©å¾ã®æ å ±ãä¸æ£ã§ã") if require.product_list != product_list: raise ValueError("å¿ è¦éã®æ å ±ãä¸æ£ã§ã") if require.material_list != material_list: raise ValueError("å¿ è¦éã®æ å ±ãä¸æ£ã§ã") self.__product_list = product_list self.__material_list = material_list self.__stock = stock self.__gain = gain self.__require = require @property def product_list(self) -> ProductList: return self.__product_list # ä»ã®ããããã£ãåæ§ï¼çç¥ def solve(self) -> tuple[int, Optional[ProductionPlan]]: """ çç£åé¡ã解ãã¦ã¹ãã¼ã¿ã¹ã¨è§£ãè¿ã Returns ------- tuple[int, Optional[ProductionPlan]] 解ã解ããã¹ãã¼ã¿ã¹ã¨è§£ã®ã㢠æé©è§£ãå¾ãããªãã£ãå ´åã解ã¯Noneãè¿ã """ x, model = self.__modeling() status = self.__solve(model) if status != pulp.LpStatusOptimal: return status, None plan = ProductionPlan({ product: x[product].value() for product in self.__product_list.items }) return status, plan def __modeling(self) -> tuple[dict[Product, pulp.LpVariable], pulp.LpProblem] # å¤æ° x = pulp.LpVariable.dicts( "x", self.__product_list.items, cat="Continuous", lowBound=0 ) # æ°çã¢ãã«ä½æ model = pulp.LpProblem("ProductionProblem", pulp.LpMaximize) # å¶ç´å¼ for material in self.__material_list.items: required = pulp.lpSum( self.__require.for_pair(product, material) for product in self.__product_list.items ) model += required <= self.__stock.for_material(material) # ç®çé¢æ° total_gain = pulp.lpSum( self.__gain.for_product(product) * x[product] for product in self.__product_list.items ) model += total_gain return x, model def __solve(self, model: pulp.LpProblem) -> int: return model.solve()
ãããã¦ããã¨ç¶æ ãæ°ã«ããå¿ è¦ããªããªãã®ã§ããªã使ãããããªãã
ããªãé·ããªã£ããã©ããããã¯ãã¬ãã«ã§ä½¿ããå®å ¨ã§å ç¢ãªã³ã¼ããæ¸ããã¨ããã¨ãå ã®ã³ã¼ãããããªãæãå ¥ããå¿ è¦ãããã æ£ç´ããªãã¡ã³ãã¤ããããã«ã¯åä½ãã¹ããæ¸ãå¿ è¦ããã£ã¦ãå®éã«ã¯ããå°ãæãæãããããããã©ã
ãã ããããã¦ããã¨åãã§ãã¯ã§åé¡ã«æ°ä»ããããç°å¸¸ãªãã¼ã¿ãç´ãè¾¼ãã®ãé²ãããããªãã¸ã§ã¯ãã®ç¶æ ãæ°ã«ããã«ä½¿ãããã¨ãã¡ãªããã大ããã åã®æ å ±ã§ã³ã¼ãã®èªã¿ããããä¸ãã£ã¦ããã
ãããã¯ããä½ã£ã¦ããã¨ã³ã¸ãã¢ã¯ãæ°çæé©åã®ç¥èã ãã§ãªãããããã£ãã½ããã¦ã§ã¢å·¥å¦ã®ç¥èã身ã«ã¤ãã¦ããããããã
ä»æ¥ã¯ããã¾ã§ï¼