周末安排生成器,输入预算,人数,偏好,自动推荐活动方案,告别选择困难。
周末安排生成器 - 智能决策系统一、实际应用场景描述场景小王计划这个周末和朋友一起出去玩但面对众多选择感到纠结。他打开周末安排生成器输入预算5000元、4个人、偏好户外美食文化系统立即生成3套不同风格的完整方案包含具体活动、费用明细、时间安排帮助他快速做决定。二、引入痛点1. 选择困难症面对海量活动选项用户难以快速筛选符合需求的组合2. 信息碎片化需要分别查景点门票、餐厅、交通费时费力3. 预算难控制多人出行时总花费容易超支4. 缺乏个性化通用攻略无法匹配个人偏好5. 时间规划乱各活动时间冲突路线不优三、核心逻辑讲解┌─────────────────────────────────────────────────────────┐│ 智能决策流程 │├─────────────────────────────────────────────────────────┤│ 1. 输入解析层 ││ └── 解析预算/人数/偏好标签 → 结构化参数 ││ ││ 2. 数据匹配层 ││ └── 根据偏好从活动库筛选候选集 ││ ├── 户外类: 登山/露营/骑行/公园 ││ ├── 美食类: 特色餐厅/夜市/咖啡馆 ││ └── 文化类: 博物馆/古镇/艺术展 ││ ││ 3. 智能组合层 (核心算法) ││ └── 动态规划 约束满足 ││ • 目标: 最大化满意度评分 ││ • 约束: 总预算 ≤ 输入预算 ││ • 约束: 活动时长合理分配(2天) ││ • 约束: 地理距离优化(减少通勤) ││ ││ 4. 方案生成层 ││ └── 输出3套方案: 经济型/平衡型/体验型 ││ • 每套含: 活动清单/时间轴/费用明细/地图建议 ││ ││ 5. 决策支持层 ││ └── 提供方案对比表 推荐理由 备选调整 │└─────────────────────────────────────────────────────────┘关键算法- 加权评分模型:Score w1*偏好匹配度 w2*性价比 w3*时间合理性- 动态规划: 在预算约束下选择最优活动组合- 贪心优化: 按地理距离排序减少通勤时间四、代码模块化实现项目结构weekend_planner/├── main.py # 主程序入口├── config.py # 配置文件├── data/│ └── activities.py # 活动数据库├── core/│ ├── input_parser.py # 输入解析器│ ├── matcher.py # 活动匹配器│ ├── optimizer.py # 智能优化器│ └── generator.py # 方案生成器├── utils/│ └── helpers.py # 工具函数└── README.md # 使用说明1. config.py - 配置文件配置模块 - 定义系统参数和权重from dataclasses import dataclassfrom typing import Dict, Listdataclassclass SystemConfig:系统全局配置# 预算缓冲比例(防止超支)BUDGET_BUFFER: float 0.9# 活动时长配置(小时)MIN_ACTIVITY_DURATION: int 2MAX_ACTIVITY_DURATION: int 6# 方案数量NUM_RECOMMENDATIONS: int 3# 评分权重SCORE_WEIGHTS: Dict[str, float] Nonedef __post_init__(self):if self.SCORE_WEIGHTS is None:self.SCORE_WEIGHTS {preference_match: 0.4, # 偏好匹配度cost_effectiveness: 0.3, # 性价比time_reasonableness: 0.2, # 时间合理性location_optimize: 0.1 # 位置优化}# 偏好标签映射PREFERENCE_TAGS {户外: [登山, 露营, 骑行, 公园, 徒步, 漂流],美食: [特色餐厅, 夜市, 咖啡馆, 甜品店, 烧烤, 火锅],文化: [博物馆, 古镇, 艺术展, 历史遗迹, 图书馆, 剧院],娱乐: [KTV, 密室逃脱, 电玩城, 电影院, 游乐园],购物: [商场, 步行街, 市集, 奥特莱斯, 免税店]}# 方案类型PLAN_TYPES {budget: 经济型,balanced: 平衡型,premium: 体验型}2. data/activities.py - 活动数据库活动数据库 - 存储所有可选活动数据每个活动包含: 名称、类型、预算范围、时长、地点、评分from dataclasses import dataclass, fieldfrom typing import List, Optionalimport randomdataclassclass Activity:活动实体类id: str # 唯一标识name: str # 活动名称category: str # 类别(户外/美食/文化/娱乐/购物)sub_category: str # 子类别base_cost_per_person: float # 单人基础费用duration_hours: float # 预计时长(小时)location: str # 地点区域satisfaction_score: float # 满意度评分(1-10)tags: List[str] # 标签列表description: str # 描述suitable_group_size: tuple # 适合人数范围(min, max)# 初始化活动数据库ACTIVITIES_DB [# 户外活动 Activity(idoutdoor_001,name西山国家森林公园徒步,category户外,sub_category徒步,base_cost_per_person35,duration_hours4,location西山,satisfaction_score8.5,tags[登山, 风景, 拍照],description登顶俯瞰城市全景秋季红叶绝佳观赏地,suitable_group_size(2, 10)),Activity(idoutdoor_002,name怀柔青龙峡露营体验,category户外,sub_category露营,base_cost_per_person180,duration_hours24,location怀柔,satisfaction_score9.2,tags[露营, 星空, 烧烤],description山谷露营包含帐篷租赁和基础装备,suitable_group_size(4, 20)),Activity(idoutdoor_003,name奥林匹克森林公园骑行,category户外,sub_category骑行,base_cost_per_person45,duration_hours3,location朝阳,satisfaction_score7.8,tags[骑行, 休闲, 亲子],description租自行车环湖骑行沿途风景优美,suitable_group_size(1, 8)),Activity(idoutdoor_004,name潮白河皮划艇漂流,category户外,sub_category漂流,base_cost_per_person120,duration_hours3,location顺义,satisfaction_score8.8,tags[漂流, 水上运动, 刺激],description双人皮划艇教练带队安全第一,suitable_group_size(2, 12)),# 美食活动 Activity(idfood_001,name簋街麻辣小龙虾盛宴,category美食,sub_category火锅,base_cost_per_person150,duration_hours3,location东城,satisfaction_score9.0,tags[小龙虾, 夜宵, 聚餐],description正宗川味多种口味可选配精酿啤酒,suitable_group_size(2, 15)),Activity(idfood_002,name南锣鼓巷胡同私房菜,category美食,sub_category特色餐厅,base_cost_per_person220,duration_hours2.5,location东城,satisfaction_score8.7,tags[胡同, 创意菜, 文艺],description藏在胡同里的网红餐厅环境雅致,suitable_group_size(2, 8)),Activity(idfood_003,name三里屯深夜食堂巡礼,category美食,sub_category夜市,base_cost_per_person180,duration_hours4,location朝阳,satisfaction_score8.3,tags[日料, 酒吧, 夜生活],description打卡3家人气餐厅配调酒师特调饮品,suitable_group_size(3, 12)),Activity(idfood_004,name798艺术区咖啡厅慢时光,category美食,sub_category咖啡馆,base_cost_per_person85,duration_hours2,location朝阳,satisfaction_score7.9,tags[咖啡, 艺术, 聊天],description工业风咖啡厅艺术家主题甜品,suitable_group_size(2, 6)),# 文化活动 Activity(idculture_001,name故宫博物院深度游览,category文化,sub_category历史遗迹,base_cost_per_person60,duration_hours5,location东城,satisfaction_score9.5,tags[历史, 建筑, 教育],description含专业讲解避开人流高峰时段,suitable_group_size(1, 20)),Activity(idculture_002,name798艺术区当代艺术展,category文化,sub_category艺术展,base_cost_per_person80,duration_hours2.5,location朝阳,satisfaction_score8.6,tags[艺术, 拍照, 现代],description3个主题展览联票含导览手册,suitable_group_size(1, 10)),Activity(idculture_003,name什刹海历史文化漫步,category文化,sub_category古镇,base_cost_per_person0,duration_hours3,location西城,satisfaction_score8.1,tags[胡同, 老北京, 免费],description步行游览黄包车体验听老北京故事,suitable_group_size(2, 15)),Activity(idculture_004,name中国科技馆探索之旅,category文化,sub_category博物馆,base_cost_per_person30,duration_hours4,location朝阳,satisfaction_score8.4,tags[科学, 互动, 亲子],description儿童免票200互动展品,suitable_group_size(1, 20)),# 娱乐活动 Activity(ident_001,name工体密室逃脱·恐怖主题,category娱乐,sub_category密室逃脱,base_cost_per_person120,duration_hours1.5,location朝阳,satisfaction_score8.2,tags[解谜, 团队, 刺激],description5人成团专业NPC多结局设计,suitable_group_size(3, 8)),Activity(ident_002,name大悦城电玩城畅玩,category娱乐,sub_category电玩城,base_cost_per_person100,duration_hours3,location朝阳,satisfaction_score7.5,tags[游戏, 抓娃娃, 放松],description200币畅玩含赛车/投篮/娃娃机,suitable_group_size(1, 6)),# 购物活动 Activity(idshop_001,name蓝色港湾欧式购物节,category购物,sub_category商场,base_cost_per_person300,duration_hours4,location朝阳,satisfaction_score7.8,tags[购物, 欧式, 餐饮],description品牌折扣湖畔餐厅一站式体验,suitable_group_size(1, 10)),Activity(idshop_002,name潘家园古玩淘宝之旅,category购物,sub_category市集,base_cost_per_person50,duration_hours2,location朝阳,satisfaction_score7.2,tags[古玩, 砍价, 淘宝],description早市淘宝专家陪同鉴宝,suitable_group_size(2, 8))]def get_activities_by_preference(preferences: List[str]) - List[Activity]:根据偏好标签获取活动列表Args:preferences: 偏好标签列表如[户外, 美食]Returns:匹配的活动列表matched_ids set()for pref in preferences:if pref in PREFERENCE_TAGS:for tag in PREFERENCE_TAGS[pref]:for activity in ACTIVITIES_DB:if tag in activity.tags and activity.id not in matched_ids:matched_ids.add(activity.id)return [a for a in ACTIVITIES_DB if a.id in matched_ids]def get_all_activities() - List[Activity]:获取所有活动return ACTIVITIES_DB.copy()3. core/input_parser.py - 输入解析器输入解析器 - 处理用户输入转换为系统可识别的结构化参数from dataclasses import dataclass, fieldfrom typing import List, Tuple, Optionalimport redataclassclass UserInput:用户结构化输入budget: float # 总预算num_people: int # 人数preferences: List[str] # 偏好列表start_date: Optional[str] None # 开始日期(可选)special_requirements: List[str] field(default_factorylist) # 特殊要求class InputParser:输入解析器类def __init__(self):self.supported_preferences [户外, 美食, 文化, 娱乐, 购物,登山, 露营, 骑行, 博物馆, 古镇,艺术展, 夜市, 咖啡馆, 密室逃脱]def parse(self, raw_input: dict) - UserInput:解析原始用户输入Args:raw_input: 原始输入字典- budget: 预算(数字或带单位字符串)- num_people: 人数(数字或文字)- preferences: 偏好(字符串逗号分隔)- start_date: 开始日期(可选)- special_requirements: 特殊要求(可选)Returns:UserInput: 结构化用户输入Raises:ValueError: 输入参数无效# 解析预算budget self._parse_budget(raw_input.get(budget, 0))# 解析人数num_people self._parse_num_people(raw_input.get(num_people, 1))# 解析偏好preferences self._parse_preferences(raw_input.get(preferences, ))# 解析特殊要求special_reqs self._parse_special_requirements(raw_input.get(special_requirements, []))return UserInput(budgetbudget,num_peoplenum_people,preferencespreferences,start_dateraw_input.get(start_date),special_requirementsspecial_reqs)def _parse_budget(self, budget_input: any) - float:解析预算输入支持格式: 5000, 5000, 5000元, 5k, 5千if isinstance(budget_input, (int, float)):return float(budget_input)if not isinstance(budget_input, str):raise ValueError(f预算格式错误: {budget_input})# 移除单位和空格budget_str budget_input.strip().lower()budget_str re.sub(r[元,\s], , budget_str)# 处理缩写multipliers {k: 1000, 千: 1000, w: 10000, 万: 10000}for suffix, multiplier in multipliers.items():if budget_str.endswith(suffix):number_part budget_str[:-len(suffix)]try:return float(number_part) * multiplierexcept ValueError:raise ValueError(f预算格式错误: {budget_input})# 纯数字try:return float(budget_str)except ValueError:raise ValueError(f预算格式错误: {budget_input})def _parse_num_people(self, people_input: any) - int:解析人数输入支持格式: 4, 4人, 四个人, 4位if isinstance(people_input, int):if people_input 1:raise ValueError(人数必须至少为1)return people_inputif not isinstance(people_input, str):raise ValueError(f人数格式错误: {people_input})people_str people_input.strip()# 提取数字numbers re.findall(r\d, people_str)if not numbers:raise ValueError(f人数格式错误: {people_input})num int(numbers[0])if num 1:raise ValueError(人数必须至少为1)if num 50:raise ValueError(人数过多请分批规划)return numdef _parse_preferences(self, pref_input: any) - List[str]:解析偏好输入支持格式: 户外,美食 或 [户外, 美食] 或 户外美食if not pref_input:return [户外, 美食] # 默认偏好if isinstance(pref_input, list):prefs pref_inputelif isinstance(pref_input, str):# 支持中英文逗号、顿号、空格分隔prefs re.split(r[,、\s], pref_input.strip())else:raise ValueError(f偏好格式错误: {pref_input})# 过滤空字符串验证有效性valid_prefs []for pref in prefs:pref pref.strip()if pref:if pref in self.supported_preferences:valid_prefs.append(pref)else:# 尝试模糊匹配matched self._fuzzy_match_preference(pref)if matched:valid_prefs.append(matched)if not valid_prefs:return [户外, 美食] # 默认偏好return list(set(valid_prefs)) # 去重def _fuzzy_match_preference(self, query: str) - Optional[str]:模糊匹配偏好标签query_lower query.lower()for pref in self.supported_preferences:if query_lower in pref.lower() or pref.lower() in query_lower:return prefreturn Nonedef _parse_special_requirements(self, reqs: any) - List[str]:解析特殊要求if not reqs:return []if isinstance(reqs, str):return [r.strip() for r in reqs.split(,) if r.strip()]if isinstance(reqs, list):return [str(r).strip() for r in reqs if r]return []def validate(self, user_input: UserInput) - Tuple[bool, str]:验证用户输入的有效性Returns:(是否有效, 错误信息)if user_input.budget 0:return False, 预算必须大于0if user_input.num_people 1:return False, 人数必须至少为1if user_input.num_people 20:return False, 当前版本支持最多20人团体if not user_input.preferences:return False, 请至少选择一个偏好return True, 输入有效4. core/matcher.py - 活动匹配器活动匹配器 - 根据用户偏好从活动库筛选候选活动from typing import List, Set, Dict, Tuplefrom data.activities import Activity, get_activities_by_preference, get_all_activitiesfrom core.input_parser import UserInputclass ActivityMatcher:活动匹配器类def __init__(self):self.all_activities get_all_activities()def match(self, user_input: UserInput) - List[Activity]:匹配符合用户偏好的活动Args:user_input: 用户结构化输入Returns:匹配的活动列表按相关性排序# 1. 根据偏好标签获取初始匹配candidate_activities get_activities_by_preference(user_input.preferences)if not candidate_activities:# 如果没有匹配返回所有活动candidate_activities self.all_activities# 2. 过滤不符合人数要求的活动filtered_activities self._filter_by_group_size(candidate_activities,user_input.num_people)# 3. 按偏好匹配度排序sorted_activities self._sort_by_preference_match(filtered_activities,user_input.preferences)return sorted_activitiesdef _filter_by_group_size(self, activities: List[Activity],num_people: int) - List[Activity]:过滤掉不适合当前人数的活动return [a for a in activitiesif a.suitable_group_size[0] num_people a.suitable_group_size[1]]def _sort_by_preference_match(self, activities: List[Activity],preferences: List[str]) - List[Activity]:按偏好匹配度对活动排序计算方式: 活动标签与用户偏好的交集数量 / 用户偏好数量def calculate_match_score(activity: Activity) - float:if not preferences:return 0.5# 计算匹配的标签数activity_tags set(activity.tags)preference_tags set()for pref in preferences:if pref in PREFERENCE_TAGS:preference_tags.update(PREFERENCE_TAGS[pref])else:preference_tags.add(pref)if not preference_tags:return 0.5match_count len(activity_tags preference_tags)return match_count / len(preference_tags)return sorted(activities, keycalculate_match_score, reverseTrue)def get_activities_by_category(self, activities: List[Activity],category: str) - List[Activity]:按类别获取活动return [a for a in activities if a.category category]def get_activities_by_location(self, activities: List[Activity],location: str) - List[Activity]:按地点获取活动if not location:return activitiesreturn [a for a in activities if location in a.location]def get_cheapest_activity(self, activities: List[Activity]) - Optional[Activity]:获取最便宜的活动if not activities:return Nonereturn min(activities, keylambda x: x.base_cost_per_person)def get_most_expensive_activity(self, activities: List[Activity]) - Optional[Activity]:获取最贵的活动if not activities:return Nonereturn max(activities, keylambda x: x.base_cost_per_person)def get_highest_rated_activity(self, activities: List[Activity]) - Optional[Activity]:获取评分最利用AI解决实际问题如果你觉得这个工具好用欢迎关注长安牧笛
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2413541.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!