【全部更新完毕】2024电工杯B题详细思路代码成品文章教学:大学生平衡膳食食谱的优化设计及评价

news2024/11/20 3:19:32

大学生平衡膳食食谱的优化设计及评价
摘要
大学阶段是学生获取知识和身体发育的关键时期,也是形成良好饮食习惯的重要阶段。然而,当前大学生中存在饮食结构不合理和不良饮食习惯的问题,主要表现为不吃早餐或早餐吃得马虎,经常食用高油高盐且营养不均衡的外卖和快餐,以及通过不科学的节食减肥,导致营养不良和健康受损。因此,大学生在这一阶段掌握营养知识并形成良好饮食习惯,对于促进生长发育和维护身体健康具有重要意义。

在本文中,针对给出的一份男大学生以及女大学生的食谱,本文从产能营养素、非产能营养素以及蛋白质氨基酸评分入手,分别计算了两个食谱对应的产能营养素、非产能营养素以及蛋白质氨基酸评分并与参考的摄入量进行对比,随后构建了TOPSIS评价模型,对产能营养素、非产能营养素以及蛋白质氨基酸评分三项指标赋予适当的权重,以参考的摄入量作为最优值对给定食谱进行评价,最后根据评价结果,我们对食谱进行一定的调整,分别为男大的食谱中减去了一个炸鸡块以及为女大食谱加上了两份米饭。

对于问题二三来说,我们综合进行考虑。首先针对氨基酸评分最大化这个目标,我们结合实际情况构建了相关的约束条件,分别包含每餐的热量摄入占比,每天的微量元素(非产能营养素)摄入情况、AAS等进行约束,随后分别采用PSO粒子群优化算法以及遗传算法对目标进行优化。最后取得不错的结果。在此基础上,分别考虑了最经济型食谱以及兼顾经济以及氨基酸评分两点作为目标的情况,同样结果不错。最后我们进一步考虑整周的食谱,考虑菜品尽可能不重复,并将其量化成约束条件,进一步给出三个优化目标下优化函数最优的食谱。

关键词:TOPSIS评价模型、遗传算法、PSO粒子群优化算法、整数规划

在这里插入图片描述

在这一小节中,我们需要对给出的附件数据进行数据预处理,以方便我们后续的模型构建。
观察到给出的附件1-3的数据文件是在同一个sheet下的多个表格,这不利于python对其进行读取以及后续操作,因此本文中,根据早餐、午餐以及晚餐三餐,将其划分成3个sheet,保存在新的excel文件中。

这样之后,我们就可以比较容易的提取出男大学生以及女大学生的三餐食谱,分别是:
男大学生:{‘早餐’: [‘小米粥’, ‘油条’, ‘煎鸡蛋’, ‘拌海带丝’],
‘午餐’: [‘大米饭’, ‘拌木耳’, ‘地三鲜’, ‘红烧肉’],
‘晚餐’: [‘砂锅面’, ‘包子’, ‘炸鸡块’]}
女大学生:{‘早餐’: [‘豆浆’, ‘鸡排面’],
‘午餐’: [‘鸡蛋饼’, ‘水饺’, ‘葡萄’],
‘晚餐’: [‘大米饭’, ‘香菇炒油菜’, ‘炒肉蒜台’, ‘茄汁沙丁鱼’, ‘苹果’]}
为了进一步计算两份食谱中的营养素等含量,我们需要对比《中国食物成分表》,从中查询了学校提供食物中包含的所有主要成分的食材对应的营养成分,统计成一个表格,下面将展示部分数据:

5.1.1营养分析评价模型
在收集好相关的膳食营养成分数据之后,下面我们需要对膳食食谱进行全面的营养分析评价,我们将按照以下步骤进行:

  1. 食物结构分析:分析食谱中食物的种类和数量,确保食物种类多样化。对于这一步我们已经在上一小节中提取出了男女两位大学生的一日食谱。
  2. 营养素含量计算:计算每种食物的营养素含量,包括热量、蛋白质、脂肪和碳水化合物。
  3. 能量及营养素评估:将计算出的营养素摄入量与推荐摄入量进行比较,评价摄入量是否符合推荐标准。
  4. 无产营养素以及AAS计算:计算每种食物的营养素含量,包括钙、铁、锌、以及各类维生素含量。随后根据给出的蛋白质氨基酸含量,进一步计算AAS。
  5. TOPSIS综合评价模型:根据计算得到的营养素含量、无产营养素以及AAS,结合推荐的每日营养素摄入量对给出的食谱进行评价。

5.1.2 模型公式

  1. 营养素含量计算公式
    对于每种食物i,其营养素 j的含量可以表示为:

    其中:
    表示食物 中营养素 的含量。
    表示食物 i 每100克中营养素 j 的含量。
    表示食物 i 的可食部重量(克)。

  2. 总营养素含量计算公式
    一日三餐的总营养素含量为所有食物营养素含量的总和:

在这里插入图片描述

5.2 问题二建模与求解

问题二包括三个优化目标:用餐费用最经济、最大化蛋白质氨基酸评分和兼顾蛋白质氨基酸评分及经济性。下面我们将详细描述每个优化目标的建模过程及数据处理步骤。

优化目标一:用餐费用最经济

  1. 数据准备:
    食物数据:包括食物名称、主要成分、价格、热量、蛋白质、脂肪、碳水化合物和蛋白质氨基酸评分(AAS)。

  2. 决策变量:
    X ij : 第 i 天第 j 种食物的份数,其中 i = 1, 2, …, j 是食物种类索引。

  3. 目标函数:

    • 最小化总费用:

    其中, c_j 是第 j 种食物的价格,N 是食物种类总数。

  4. 约束条件:

    • 每天的热量需求:

    其中, e_j 是第 j 种食物的热量。

    • 每天的蛋白质需求:

    其中, p_j 是第 j 种食物的蛋白质含量。

    • 每天的脂肪需求:

    其中, f_j 是第 j 种食物的脂肪含量。

    • 每天的碳水化合物需求:

    其中, c_j 是第 j 种食物的碳水化合物含量。

    • 每天的食物份数限制:

    • 食物份数非负:

优化目标二:最大化蛋白质氨基酸评分

  1. 数据准备:

    • 同优化目标一的数据准备步骤。
  2. 决策变量:
    x_ij : 第 i 天第 j 种食物的份数,其中 i = 1, 2, …, j 是食物种类索引。

  3. 目标函数:

    • 最大化总蛋白质氨基酸评分:

其中, aas_j 是第 j 种食物的蛋白质氨基酸评分。

  1. 约束条件:同优化目标一的约束条件。

优化目标三:兼顾蛋白质氨基酸评分及经济性

在这里插入图片描述

核心代码:

# 定义评估函数以最小化费用
def evaluate_cost(individual):
    x_morning = individual[:len(foods_morning_grouped)]
    x_lunch = individual[len(foods_morning_grouped):len(foods_morning_grouped)+len(foods_lunch_grouped)]
    x_dinner = individual[len(foods_morning_grouped)+len(foods_lunch_grouped):]
    
    total_cost = np.dot(x_morning, foods_morning_grouped['价格\n(元/份)'].values) + np.dot(x_lunch, foods_lunch_grouped['价格\n(元/份)'].values) + np.dot(x_dinner, foods_dinner_grouped['价格\n(元/份)'].values)
    
    total_energy = np.dot(x_morning, foods_morning_grouped['热量 (kcal)'].values) + np.dot(x_lunch, foods_lunch_grouped['热量 (kcal)'].values) + np.dot(x_dinner, foods_dinner_grouped['热量 (kcal)'].values)
    total_protein = np.dot(x_morning, foods_morning_grouped['蛋白质 (g)'].values) + np.dot(x_lunch, foods_lunch_grouped['蛋白质 (g)'].values) + np.dot(x_dinner, foods_dinner_grouped['蛋白质 (g)'].values)
    total_fat = np.dot(x_morning, foods_morning_grouped['脂肪 (g)'].values) + np.dot(x_lunch, foods_lunch_grouped['脂肪 (g)'].values) + np.dot(x_dinner, foods_dinner_grouped['脂肪 (g)'].values)
    total_carb = np.dot(x_morning, foods_morning_grouped['碳水化合物 (g)'].values) + np.dot(x_lunch, foods_lunch_grouped['碳水化合物 (g)'].values) + np.dot(x_dinner, foods_dinner_grouped['碳水化合物 (g)'].values)
    total_servings = np.sum(individual)
    
    penalty = 0
    
    if total_energy > 4000:
        penalty += (total_energy - 4000) * 10
    if total_energy < 2400:
        penalty += (2400 - total_energy) * 10
    if total_protein < 60:
        penalty += (60 - total_protein) * 10
    if total_fat < 53:
        penalty += (53 - total_fat) * 10
    if total_carb < 300:
        penalty += (300 - total_carb) * 10
    if total_servings > 25:
        penalty += (total_servings - 25) * 10
    
    return total_cost + penalty,

toolbox.register("evaluate", evaluate_cost)

在这里插入图片描述

问题三核心代码:

# 删除已存在的类
if hasattr(creator, "FitnessMin"):
    del creator.FitnessMin
if hasattr(creator, "Individual"):
    del creator.Individual

# 创建最小化问题的fitness function
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))

# 创建个体和种群
creator.create("Individual", list, fitness=creator.FitnessMin)

toolbox = base.Toolbox()

# 定义个体生成函数,生成整数列表,表示每种食物的份数
toolbox.register("attr_int", random.randint, 0, 10)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_int, n=len(foods_grouped) * 7)

# 定义种群生成函数
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

# 注册选择函数
toolbox.register("select", tools.selTournament, tournsize=3)

# 注册交叉和变异函数
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutUniformInt, low=0, up=10, indpb=0.2)

# 评估函数:兼顾蛋白质氨基酸评分及经济性
def evaluate_weekly_combined(individual):
    total_cost = 0
    total_aas = 0
    penalty = 0
    unique_meals = set()
    
    for day in range(7):
        x_day = individual[day*len(foods_grouped):(day+1)*len(foods_grouped)]
        x_morning = x_day[:len(foods_morning_grouped)]
        x_lunch = x_day[len(foods_morning_grouped):len(foods_morning_grouped)+len(foods_lunch_grouped)]
        x_dinner = x_day[len(foods_morning_grouped)+len(foods_lunch_grouped):]
        
        day_cost = np.dot(x_morning, foods_morning_grouped['价格\n(元/份)'].values) + \
                   np.dot(x_lunch, foods_lunch_grouped['价格\n(元/份)'].values) + \
                   np.dot(x_dinner, foods_dinner_grouped['价格\n(元/份)'].values)
        total_cost += day_cost
        
        day_aas = np.dot(x_morning, foods_morning_grouped['AAS'].values) + \
                  np.dot(x_lunch, foods_lunch_grouped['AAS'].values) + \
                  np.dot(x_dinner, foods_dinner_grouped['AAS'].values)
        total_aas += day_aas
        
        day_energy = np.dot(x_morning, foods_morning_grouped['热量 (kcal)'].values) + \
                     np.dot(x_lunch, foods_lunch_grouped['热量 (kcal)'].values) + \
                     np.dot(x_dinner, foods_dinner_grouped['热量 (kcal)'].values)
        day_protein = np.dot(x_morning, foods_morning_grouped['蛋白质 (g)'].values) + \
                      np.dot(x_lunch, foods_lunch_grouped['蛋白质 (g)'].values) + \
                      np.dot(x_dinner, foods_dinner_grouped['蛋白质 (g)'].values)
        day_fat = np.dot(x_morning, foods_morning_grouped['脂肪 (g)'].values) + \
                  np.dot(x_lunch, foods_lunch_grouped['脂肪 (g)'].values) + \
                  np.dot(x_dinner, foods_dinner_grouped['脂肪 (g)'].values)
        day_carb = np.dot(x_morning, foods_morning_grouped['碳水化合物 (g)'].values) + \
                   np.dot(x_lunch, foods_lunch_grouped['碳水化合物 (g)'].values) + \
                   np.dot(x_dinner, foods_dinner_grouped['碳水化合物 (g)'].values)
        day_servings = np.sum(x_day)

        # 计算不重复食谱的惩罚
        day_meal = tuple(x_day)
        if day_meal in unique_meals:
            penalty += 1000  # 对重复食谱进行高惩罚
        else:
            unique_meals.add(day_meal)
        
        if day_energy > 4000:
            penalty += (day_energy - 4000) * 10
        if day_energy < 2400:
            penalty += (2400 - day_energy) * 10
        if day_protein < 60:
            penalty += (60 - day_protein) * 10
        if day_fat < 53:
            penalty += (53 - day_fat) * 10
        if day_carb < 300:
            penalty += (300 - day_carb) * 10
        if day_servings > 25:
            penalty += (day_servings - 25) * 10
    
    return total_cost - total_aas + penalty,

toolbox.register("evaluate", evaluate_weekly_combined)

# 设置遗传算法的参数
population = toolbox.population(n=1000)  # 种群大小
ngen = 3000  # 迭代次数
cxpb = 0.7  # 交叉概率
mutpb = 0.2  # 变异概率

# 运行遗传算法
algorithms.eaSimple(population, toolbox, cxpb, mutpb, ngen, stats=None, halloffame=None, verbose=True)

# 获取最优解
best_individual = tools.selBest(population, k=1)[0]

print("最优解:", best_individual)
print("最优值:", toolbox.evaluate(best_individual))
## 2024电工杯助攻详情
## docs.qq.com/doc/DVWRIQUlKaVNqcWFr

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

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

相关文章

JVM学习-垃圾收集器(三)

G1回收器-区域化分代式 为了适应不断扩大的内存和不断增加的处理器数量&#xff0c;进一步降低暂停时间&#xff0c;同时兼顾良好的吞吐量官方给G1设定的目标&#xff1a;延迟可控的情况下获得尽可能高的吞吐量&#xff0c;所以才担当起“全功能收集器”的重任与期望G1是一款面…

构建数字未来:探索Web3在物联网中的新视角

引言 随着Web3时代的来临&#xff0c;物联网技术正迎来一场新的变革。在这个数字化时代&#xff0c;Web3所带来的技术创新将为物联网的发展开辟新的视角。本文将深入探讨Web3在物联网领域的应用&#xff0c;揭示其在构建数字未来中的重要性和影响。 Web3与物联网的融合 区块链…

Docker学习笔记(二)Dockerfile自定义镜像、DockerCompose、Docker私有镜像仓库

文章目录 前言3 Dockerfile自定义镜像3.1 镜像结构3.2 Dockerfile文件3.3 构建自定义镜像3.3.1 基于Ubuntu构建Java项目3.3.2 基于Java8构建Java项目 3.4 小结 4 DockerCompose4.1 安装DockerCompose4.2 部署微服务集群 5 Docker私有镜像仓库 前言 Docker学习笔记(一)安装Dock…

ctfhub中的SSRF的相关例题(下)

目录 URL Bypass 知识点 相关例题 数字IP Bypass 相关例题 方法一&#xff1a;使用数字IP 方法二&#xff1a;转16进制 方法三&#xff1a;用localhost代替 方法四&#xff1a;特殊地址 302跳转 Bypass ​编辑 关于localhost原理: DNS重绑定 Bypass 知识点&…

每日练习之数学——砝码和天平

砝码和天平 题目描述 运行代码 #include<iostream> using namespace std; int main() {int w,m,T;cin>>T;while(T--){cin>>w>>m;while(m){if((m-1)%w0)m(m-1)/w;else if((m1)%w0)m(m1)/w;else if(m%w0)m/w;else break;}if(!m)cout<<"YES&…

「职场必备」让你摆脱思维混乱的7个工具

1. 升维思考&#xff0c;降维拆解 解决复杂问题时&#xff0c;有两个关键的阶段&#xff0c;能让我们事半功倍。 第一个阶段是思考阶段&#xff0c;要自下而上进行“升维思考”&#xff0c;明确问题的本质是什么。第二阶段是行动阶段&#xff0c;要自上而下进行“降维拆解”&am…

Excel查找匹配函数(VLOOKUP):功能与应用解析

文章目录 概述VLOOKUP函数语法查询并返回单列结果查找并返回多列结果MATCH函数VLOOKUPMATCH 从右向左逆向查找&#xff1a;INDEX函数INDEXMATCH 函数匹配方式查找匹配注意事项函数名称错误: #NAME?值错误&#xff1a;#VALUE!引用错误&#xff1a;#REF!找不到数据&#xff1a;#…

1、NLP分词

分词处理 1、token&#xff08;词汇单元&#xff09;2、Tokenizer&#xff08;分词&#xff09;3、ElasticSearch 分词器&#xff08;Analyzer&#xff09;4、分词工具停用词&#xff08;Stop words&#xff09; 1、token&#xff08;词汇单元&#xff09; “token”主要用于文…

AI早班车5.25

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是「奇点」&#xff0c;江湖人称 singularity。刚工作几年&#xff0c;想和大家一同进步&#x1f91d;&#x1f91d; 一位上进心十足的【Java ToB端大厂…

51-53 DriveWorld:通过自动驾驶世界模型进行 4D 预训练场景理解 (含模型数据流梳理)

24年5月&#xff0c;北京大学、国防创新研究院无人系统技术研究中心、中国电信人工智能研究院联合发布了DriveWorld: 4D Pre-trained Scene Understanding via World Models for Autonomous Driving。 DriveWorld在UniAD的基础上又有所成长&#xff0c;提升了自动驾驶目标检测…

linux之防火墙工具

netfilter Linux防火墙是由Netfilter组件提供的&#xff0c;Netfilter工作在内核空间&#xff0c;集成在linux内核中。 Netfilter在内核中选取五个位置放了五个hook(勾子) function(INPUT、OUTPUT、FORWARD、PREROUTING、POSTROUTING)&#xff0c;而这五个hook function向用户…

人工智能应用-实验8-用生成对抗网络生成数字图像

文章目录 &#x1f9e1;&#x1f9e1;实验内容&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;代码&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;分析结果&#x1f9e1;&#x1f9e1;&#x1f9e1;&#x1f9e1;实验总结&#x1f9e1;&#x1f9e1; &#x1f9…

Stable Diffusion【艺术特效】【霓虹灯】:霓虹灯像素化马赛克特效

提示词 Neon pixelated mosaic of [Subject Description],highly detailed [主题]的霓虹灯像素化马赛克&#xff0c;高度详细 参数设置 大模型&#xff1a;万享XL_超写实摄影V8.2 采样器&#xff1a;Euler a 采样迭代步数&#xff1a;25 CFG&#xff1a;3 反向提示词&#x…

Docker Desktop安装和如何在WSL2中使用Docker

最近在使用WSL的过程中&#xff0c;想使用docker遇到了一些问题&#xff0c;在WSL中安装Linux版本的docker&#xff0c;启动镜像之后不能从Windows机器的端口映射出来&#xff0c;查了一圈之后&#xff0c;发现应该使用Docker Desktop软件&#xff0c;下面是安装和使用的方式 …

UE5 双手握剑的实现(逆向运动学IK)

UE5 双手握剑的实现 IK 前言 什么是IK&#xff1f; UE官方给我们提供了很多对于IK处理的节点&#xff0c;比如ABRIK、Two Bone IK、Full Body IK 、CCD IK等&#xff0c;但是看到这&#xff0c;很多人就好奇了&#xff0c;什么是IK&#xff1f; 首先我们来看看虚幻小白人的骨…

实战Java虚拟机-实战篇

一、内存调优 1.内存溢出和内存泄漏 内存泄漏&#xff08;memory leak&#xff09;&#xff1a;在Java中如果不再使用一个对象&#xff0c;但是该对象依然在GC ROOT的引用链上&#xff0c;这个对象就不会被垃圾回收器回收&#xff0c;这种情况就称之为内存泄漏。内存泄漏绝大…

图论(二)-图的建立

引言&#xff1a; 建图&#xff0c;将图放进内存的方法 常用的建图方式&#xff1a;邻接矩阵&#xff0c;邻接链表&#xff0c;链式前向星 一、邻接矩阵 通过一个二维数组即可将图建立&#xff0c;邻接矩阵&#xff0c;考虑节点集合 &#xff0c;用一个二维数组定义邻接矩…

自定义原生小程序顶部及获取胶囊信息

需求&#xff1a;我需要将某个文字或者按钮放置在小程序顶部位置 思路&#xff1a;根据获取到的顶部信息来定义我需要放的这个元素样式 * 这里我是定义某个指定页面 json&#xff1a;给指定页面的json中添加自定义设置 "navigationStyle": "custom" JS&am…

子分支想主分支发起合并请求

请求合并 1.点击 git Web 页右上角打开 Merge requests 进入新页&#xff0c;点击右上角。注意选择要合并的项目 2.左边是源分支&#xff0c;右边是要合并的目标分支。 3.最后点击左下角绿色按钮 4.第一个红框 Assignee&#xff0c;选择要通知去合并的人。第二个红框不动&#…

BUUCTF---web---[BJDCTF2020]ZJCTF,不过如此

1、点开连接&#xff0c;页面出现了提示 传入一个参数text&#xff0c;里面的内容要包括I have a dream。 构造&#xff1a;?/textI have a dream。发现页面没有显示。这里推测可能得使用伪协议 在文件包含那一行&#xff0c;我们看到了next.php的提示&#xff0c;我们尝试读取…