不放回抽样_生成不重样菜单

任务背景:
某餐馆有猪肉菜、牛羊肉、家禽、鱼类等菜品分类,想制作每天中晚餐不重复菜单,要求每顿菜品由猪+其他组成,且最好不要连续都是猪肉的皮排骨、烧肉系列,要间隔开。

from openpyxl.styles import Alignment
import random
from collections import dequedef generate_non_repeating_meals(total_days=56):"""菜单生成器"""pork_categories = {'pork_1': ["红烧肉", "萝卜烧肉", "豆泡烧肉", "海带烧肉", "鹌鹑蛋烧肉","莲藕烧肉", "毛芋仔烧肉", "香菇烧肉", "虎皮蛋烧肉", "干豆条烧肉","板栗烧肉", "咸鱼烧肉", "鱼蛋烧肉", "鹿茸菇烧肉", "梅干菜烧肉", "鲍鱼烧肉"],'pork_2': ["粉蒸排骨", "糯米排骨", "萝卜烧排骨", "鹌鹑蛋烧排骨", "莲藕烧排骨","香芋蒸排骨", "糖醋排骨", "红烧大排", "荔浦芋头烧排", "土豆焖排骨", "豉香排骨"],'pork_3': ["红烧猪脚", "梅菜猪脚", "黄豆猪脚"],'pork_4': ["米粉蒸肉", "红烧狮子头", "盐菜扣肉", "太阳蛋"]}other_categories = {'beef': ['红烧牛杂', '红烧牛腩', '牛腩烧萝卜', '牛腩腐竹', '回锅牛肉','杭椒牛柳', '黑椒牛仔骨', '牛腩烧牛肚', '牛腩烧牛筋', '羊肉烧红萝卜','红烧羊肉', '葱爆牛肉', '孜然羊排'],'poultry': ['香辣鸭三件', '辣子鸡', '红烧鸡', '香菇烧鸡', '白切鸡','香酥鸭', '虎皮凤爪', '鹌鹑蛋凤爪', '啤酒鸭', '红烧鸭','香菇烧鸣', '烤鸭', '板鸭炖豆腐', '板鸭烧萝卜', '红烧鸡腿','可乐鸡中翅', '香辣卤鸡腿', '糯米蒸鸡', '莲花血鸭', '仔姜烧鹅','大盘鸡'],'fish': ['红烧鱼块', '南昌小炒鱼', '红烧鲫鱼', '红烧带鱼', '酒糟鱼','酸菜鱼丸', '白灼基围虾', '深海鱼尾', '小黄鱼', '酸菜鱼','鲇鱼烧豆腐', '香酥椒盐虾', '蒜蓉基围虾']}# 初始化状态last_used = {cat: deque(maxlen=3) for cat in ['pork_1', 'pork_2', 'pork_3']}used_dishes = {cat: set() for cat in pork_categories}used_other_dishes = {cat: set() for cat in other_categories}# 记录各类别的使用次数usage_count = {cat: 0 for cat in pork_categories}# 总餐数total_meals = total_days * 2  def select_category(category_name):"""选择指定类别的菜品"""available = [d for d in pork_categories[category_name] if d not in used_dishes[category_name]]if not available:# 重置该类别的已使用记录used_dishes[category_name] = set()available = pork_categories[category_name]dish = random.choice(available)used_dishes[category_name].add(dish)return dishdef select_pork(meal_type, day):"""选择猪肉菜品并更新状态"""nonlocal usage_countavailable_cats = []# 首先检查有间隔限制的类别 (pork_1, pork_2, pork_3)for cat in ['pork_1', 'pork_2', 'pork_3']:# 检查间隔限制 - 增加到3顿间隔if last_used[cat]:last_day, last_meal_type = last_used[cat][-1]# 检查是否间隔足够(至少间隔3顿)# 如果同一天,或者第二天,或者第三天同一餐次,都不能使用if (day == last_day) or \(day == last_day + 1) or \(day == last_day + 2 and meal_type == last_meal_type):continue# 检查可用菜品available = [d for d in pork_categories[cat] if d not in used_dishes[cat]]if available:available_cats.append((cat, available))# 计算当前pork_4的使用率pork_4_usage_rate = usage_count['pork_4'] / total_meals if total_meals > 0 else 0# 决定是否使用pork_4 - 更严格的控制use_pork_4 = False# 只有在以下情况下才使用pork_4:# 1. 没有其他可用类别# 2. pork_4使用率低于25%且随机概率很低if not available_cats:use_pork_4 = Trueelif pork_4_usage_rate < 0.25 and random.random() < 0.05:  # 降低到5%概率use_pork_4 = True# 优先选择pork_1和pork_2if available_cats and not use_pork_4:# 给pork_1和pork_2更高的权重weighted_cats = []for cat, dishes in available_cats:if cat == 'pork_1':weighted_cats.extend([(cat, dishes)] * 4)  # 增加pork_1权重为4elif cat == 'pork_2':weighted_cats.extend([(cat, dishes)] * 3)  # 增加pork_2权重为3else:  # pork_3weighted_cats.append((cat, dishes))  # pork_3权重为1cat, dishes = random.choice(weighted_cats)dish = random.choice(dishes)used_dishes[cat].add(dish)usage_count[cat] += 1# 更新使用记录if cat in ['pork_1', 'pork_2', 'pork_3']:last_used[cat].append((day, meal_type))return dish, catelse:# 使用pork_4available_pork_4 = [d for d in pork_categories['pork_4'] if d not in used_dishes['pork_4']]if available_pork_4:dish = random.choice(available_pork_4)used_dishes['pork_4'].add(dish)usage_count['pork_4'] += 1return dish, 'pork_4'else:# 如果pork_4不可用,尝试重置其他类别for cat in ['pork_1', 'pork_2', 'pork_3']:if not [d for d in pork_categories[cat] if d not in used_dishes[cat]]:used_dishes[cat] = set()  # 重置该类别的已使用记录# 重新检查可用类别available_cats = []for cat in ['pork_1', 'pork_2', 'pork_3']:if last_used[cat]:last_day, last_meal_type = last_used[cat][-1]if (day == last_day) or \(day == last_day + 1) or \(day == last_day + 2 and meal_type == last_meal_type):continueavailable = [d for d in pork_categories[cat] if d not in used_dishes[cat]]if available:available_cats.append((cat, available))if available_cats:# 使用权重选择weighted_cats = []for cat, dishes in available_cats:if cat == 'pork_1':weighted_cats.extend([(cat, dishes)] * 4)elif cat == 'pork_2':weighted_cats.extend([(cat, dishes)] * 3)else:weighted_cats.append((cat, dishes))cat, dishes = random.choice(weighted_cats)dish = random.choice(dishes)used_dishes[cat].add(dish)usage_count[cat] += 1if cat in ['pork_1', 'pork_2', 'pork_3']:last_used[cat].append((day, meal_type))return dish, catelse:# 紧急情况使用pork_4(重置)used_dishes['pork_4'] = set()dish = random.choice(pork_categories['pork_4'])used_dishes['pork_4'].add(dish)usage_count['pork_4'] += 1return dish, 'pork_4'def select_other():"""选择其他肉类"""available_cats = []for cat, dishes in other_categories.items():available = [d for d in dishes if d not in used_other_dishes[cat]]if available:available_cats.append((cat, available))if not available_cats:# 重置所有其他肉类池for cat in other_categories:used_other_dishes[cat] = set()available_cats = [(cat, dishes) for cat, dishes in other_categories.items()]cat, dishes = random.choice(available_cats)dish = random.choice(dishes)used_other_dishes[cat].add(dish)return dish# 生成菜单meals = []for day in range(total_days):# 午餐lunch_pork, lunch_pork_type = select_pork('lunch', day)lunch_other = select_other()# 晚餐dinner_pork, dinner_pork_type = select_pork('dinner', day)dinner_other = select_other()meals.append({'lunch': [lunch_pork, lunch_other],'dinner': [dinner_pork, dinner_other],'lunch_pork_type': lunch_pork_type,'dinner_pork_type': dinner_pork_type})return mealsdef write_meat_to_all_sheets(file_path, output_path):"""Excel写入器"""wb = load_workbook(file_path)all_meals = generate_non_repeating_meals(56)# 按周分组weekly_meals = [all_meals[i * 7:(i + 1) * 7] for i in range(8)]for sheet_idx, (sheet_name, week_meals) in enumerate(zip(wb.sheetnames, weekly_meals)):if sheet_idx >= len(weekly_meals):breakws = wb[sheet_name]# 指定写入数据列(A、C、E、G、I、K、M列)odd_columns = [1, 3, 5, 7, 9, 11, 13]# 写入数据for day, meals in enumerate(week_meals):col = odd_columns[day]# 午餐ws.cell(row=4, column=col, value=meals['lunch'][0])ws.cell(row=5, column=col, value=meals['lunch'][1])# 晚餐ws.cell(row=11, column=col, value=meals['dinner'][0])ws.cell(row=12, column=col, value=meals['dinner'][1])# 设置格式for row in [4, 5, 11, 12]:for col in odd_columns:ws.cell(row=row, column=col).alignment = Alignment(horizontal='center',vertical='center',wrap_text=True)print(f"已处理 sheet【{sheet_name}】的肉类数据")wb.save(output_path)print(f"所有肉类数据已写入: {output_path}")# 打印统计信息print("\n菜单统计:")pork_types_count = {"pork_1": 0, "pork_2": 0, "pork_3": 0, "pork_4": 0}for meal in all_meals:pork_types_count[meal['lunch_pork_type']] += 1pork_types_count[meal['dinner_pork_type']] += 1total_pork_meals = sum(pork_types_count.values())for cat, count in pork_types_count.items():percentage = count / total_pork_meals * 100print(f"{cat}使用次数: {count} ({percentage:.1f}%)")if __name__ == "__main__":input_path = r'D:\文档\WXWork\1688855493661308\Cache\File\2025-11\食堂菜单 - 副本.xlsm'output_path = r'D:\优化版食堂菜单.xlsx'write_meat_to_all_sheets(input_path, output_path)```

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/955492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025 年点胶机源头厂家最新推荐排行榜:自动 / 果冻胶 / 无痕内衣 / 烫钻 / 珠宝热熔胶等专用设备优选企业榜单

引言 当前工业自动化进程加速,点胶机作为关键生产设备,已广泛应用于 LED 光电、服装、医疗器械、消费电子等多个领域,不同行业对设备的精度、适配胶水类型、生产效率等需求差异显著。然而,市场上点胶机厂家数量繁杂…

CTFshow Web入门之JWT篇wp

JWTwp Web345(None空加密算法) 抓包后得到jwt 发现不存在第三部分的签证,也就不需要知道密钥。base64解码后将user改为admin尝试直接拼接,发现不行发现还有一步忘了,就是alg的类型应该写HS256拼接后,发现还是不行(…

算力成本降低 33%,与光同尘用 Serverless AI 赋能影视商业内容生产

对与光同尘而言,阿里云函数计算不仅是技术工具,更是战略伙伴。它让一家初创影视公司得以用极低的门槛,获得媲美科技巨头的算力能力;让百人团队能发挥千人规模的生产力;让中国创意得以高效、低成本地走向世界。作者…

2025 年国内时钟系统厂家最新推荐排行榜:聚焦实力企业,助力各领域精准选品子母钟时钟系统/北斗时钟系统/网络时钟系统/ntp 时钟系统公司推荐

引言 在数字化转型加速推进的当下,时钟系统作为核电、电力、交通、医疗等关键领域的 “时间基准”,其精度与稳定性直接关乎行业运行安全与效率。然而当前市场中,时钟系统厂商技术水平悬殊,部分企业产品难以满足高端…

顶会论文解读:时序数据库 Apache IoTDB 中的时序数据压缩优化【VLDB 2025】

时序数据库 Apache IoTDB 顶会论文获中国信通院数据库应用创新实验室深度解读!时序数据库 Apache IoTDB 顶会论文获中国信通院数据库应用创新实验室深度解读!以下为详解原文: 本文对清华大学王建民教授团队、中国人…

ASP.NET Core Blazor 核心功能二:Blazor表单和验证

大家好,我是码农刚子。本文介绍了Blazor中EditForm组件的使用及表单验证方案。主要内容包括: 1)EditForm基础用法,通过Model参数绑定模型,使用DataAnnotationsValidator实现数据注解验证; 2)自定义验证规则实现…

2025年11月黄黑皮美白面霜推荐榜:十款持证淡斑产品口碑排行

站在镜子前,你或许正为肤色暗沉、痘印难消而反复试错:黄黑皮本身黑色素活跃,稍受紫外线或熬夜刺激,色斑便加深;市面美白成分常伴随刺痛、脱皮,敏感肌更不敢轻易尝试;再加上“持证”信息分散、浓度标注不清,选品…

2025年11月黄黑皮美白产品评测榜:十款温和提亮面霜排名一览

站在镜子前,你或许正为肤色暗沉、痘印难消而叹气:粉底盖不住,遮瑕又显灰,拍照永远靠滤镜。黄黑皮的美白诉求并非“一夜漂白”,而是希望在不刺激、不反黑的前提下,让肤色均匀、透亮、有生气。2025年《中国皮肤健康…

2025年11月常州光伏公司排名最新榜单:十大企业综合实力对比分析

摘要 随着碳中和目标的推进,常州光伏产业迎来新一轮发展机遇。本文基于企业规模、技术创新、市场口碑等维度,对常州光伏公司排名进行全面评估,旨在为行业投资者和终端用户提供参考。榜单数据来源于权威行业报告及企…

QP(状态机事件驱动型框架)

1 QP框架为什么简称QP QP 这个简称可以理解为: 1)Quantum(量子) + Platform(平台) = QP 2)量子跃迁是指微观粒子(如原子或分子)从一个量子态突然转变到另一个量子态的过程,伴随能量的吸收或释放。 3)一个借…

深圳市德恺检测有限公司:您的CNAS/CMA实验室认证咨询专业伙伴

深圳市德恺检测有限公司专注CNAS/CMA实验室认证一站式“包过”服务,10+年经验、500+成功案例,帮助企业高效获证,提升公信力与利润。覆盖双认证、扩项维护,适用于检测、校准领域,助力2025年市场竞争力。 在检测市场…

2025 最新智能食堂秤厂家/推荐排行榜:溯源 / 验收 / 留样秤品牌权威盘点及选购指南食堂验收智能秤/生鲜分拣智能秤/留样智能秤公司推荐

引言 智慧食堂建设的加速推进,让智能食堂秤成为保障食材计量精准、提升运营效率的核心设备,市场需求持续攀升。但当前市场乱象丛生:部分品牌缺乏核心技术,产品存在称重误差大、稳定性不足等问题;部分厂家服务体系…

贪心题目小结

题目壹 货物堆叠 时间限制:1秒 | 内存限制:128兆字节 题目描述 商店中有 n 件货物,每件货物 i 有重量 wi、初始体积 vi 和压缩系数 ci。将货物堆叠成一堆时,货物 i 的实际体积为 vi - ci * W,其中 W 是其上方所有…

faust-一个可以切换合成器音色的lfo demo

faust-一个可以切换合成器音色的lfo demoimport("stdfaust.lib");// 0 1 2 3: sin,tri,saw,square wave_shape = hslider("合成器波形选择[style:knob]",0,0,3,1);// 0 1 2 3: sin,tri,saw,square…

AGC052 VP

AGC 052 [AGC052A] Long Common Subsequence skip。 [AGC052B] Tree Edges XOR 给定一棵树,每条边有初始权值和目标权值,每次可以选择一条当前权值为 \(w\) 连接 \(u\),\(v\) 的边,将其他与 \(u\) 或 \(v\) 相连的…

2025 年液位计厂家最新推荐榜单:涵盖投入式 / 磁致伸缩 / 防爆 / 防水 / 浮球等类型,全面解析行业领先品牌技术与市场优势

引言 在工业生产与各类工程应用中,液位计是保障生产安全、提升效率的关键设备。但当前市场品牌繁杂,产品性能差异显著,为帮助用户精准选择,行业协会联合专业测评机构开展了 2025 年液位计品牌测评工作。 测评采用多…

落地案例分享 | 个人决策平台界面设计

落地案例分享 | 个人决策平台界面设计

2025学习机黑马登场!松鼠AI S20实测两个月——孩子主动刷题、精准提分不是梦

🏁 开篇:松鼠AI S20,2025年学习机中的真正黑马 2025年9月选学习机时,我没有追随“热门大牌”,而是选择了深耕自适应教育11年的专业品牌——松鼠AI。最终花近6000元入手它的旗舰机型:松鼠AI S20学习机。 作为测评…

【URP】Unity[后处理]颜色查询ColorLookup

技术定义与核心作用 ColorLookup是基于LUT(Lookup Table)技术的颜色映射系统,通过预定义的256x16像素条状PNG纹理实现全局色彩替换。其核心价值在于: ‌风格统一‌:批量修【从UnityURP开始探索游戏渲染】专栏-直达…