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

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

在本文中,针对给出的一份男大学生以及女大学生的食谱,本文从产能营养素、非产能营养素以及蛋白质氨基酸评分入手,分别计算了两个食谱对应的产能营养素、非产能营养素以及蛋白质氨基酸评分并与参考的摄入量进行对比,随后构建了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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python文件和数据格式化-课后作业[python123题库]

文件和数据格式化-课后作业 一、单项选择题 1、文件句柄f&#xff0c;以下是f.seek(0)作用的是&#xff1a;‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‪…

如何从http免费升级到https

使用https协议开头是为了在用户访问网站时提供更安全的网络环境。相比http&#xff0c;使用https有数据加密、身份验证、保护隐私、搜索引擎优化等优势。一般获取https证书&#xff0c;则需要支付费用给证书颁发机构&#xff08;CA&#xff09;。还有一些免费的证书证书颁发机构…

嵌入式单片机启动地址映射关系

一、内核只会从0地址启动 1.0地址第一个字是sp栈指针,第二个字是Reset_Handler入口,参考图1中启动代码中的中断向量表。具体使用流程参考图2(参考自野火) 图1 图2 2.0地址映射以后,软件上使用0地址访问的空间是映射到的器件的空间 3.0地址映射只会影响单个器件上的地址,…

知识图谱数据预处理笔记

知识图谱数据预处理笔记 0. 引言1. 笔记1-1. \的转义1-2. 特殊符号的清理1-3. 检查结尾是否正常1-4. 检查<>是否存在1-5. 两端空格的清理1-6. 检查object内容长时是否以<开始 0. 引言 最近学习知识图谱&#xff0c;发现数据有很多问题&#xff0c;这篇笔记记录遇到的…

数据可视化

目录 数据可视化: 常见的数据可视化库: Echarts 使用五步曲 Echarts 相关配置 数据可视化: 应对现在数据可视化趋势,越来越多企业需要在很多场景(营销数据,生产数据,用户数据)下使用,可视化图表来展示体现数据,让数据更加直观,数据特点更加突出 主要目的:借助于…

小红书-社区搜索部 (NLP、CV算法实习生) 一面面经

&#x1f604; 整个流程按如下问题展开&#xff0c;用时60min左右面试官人挺好&#xff0c;前半部分问问题&#xff0c;后半部分coding一道题。 各位有什么问题可以直接评论区留言&#xff0c;24小时内必回信息&#xff0c;放心~ 文章目录 1、自我介绍2、介绍下项目&#xff…

Node.js知识点以及案例总结

思考&#xff1a;为什么JavaScript可以在浏览器中被执行 每个浏览器都有JS解析引擎&#xff0c;不同的浏览器使用不同的JavaScript解析引擎&#xff0c;待执行的js代码会在js解析引擎下执行 为什么JavaScript可以操作DOM和BOM 每个浏览器都内置了DOM、BOM这样的API函数&#xf…

好用的window粘贴板

可以设置指定的快捷键&#xff0c;在需要使用最近复制的记录时快速的复用 -> Ditto。 选择Download即可 地址&#xff1a;Ditto clipboard manager (sourceforge.io)https://ditto-cp.sourceforge.io/

SwiftUI中的组合动画(Simultaneous, Sequenced, Exclusive)

了解了常见的几种手势后&#xff0c;接下来我们了解一下组合手势的操作&#xff0c;当一个视图存在多个手势的时候&#xff0c;为了避免手势冲突&#xff0c;SwiftUI提供了自定义手势的方法&#xff0c;比如同时进行&#xff0c;顺序进行等等。 以下是一些常见的多种手势组合使…

集创北方ICN6211 MIPIDSI桥接到RGB,支持RGB565/RGB888/RGB666

ICN6211描述&#xff1a; ICN6211是一个桥接芯片&#xff0c;它接收MIPIDSI输入并发送RGB输出。MIPIDSI最多支持4个车道&#xff0c;每个车道的最大运行频率为1Gbps&#xff1b;总最大输入带宽为4Gbps&#xff1b;并且还支持MIPI定义的ULPS&#xff08;超低功耗状态&#xff0…

计算机网络基础 - 计算机网络和因特网(1)

计算机网络基础 计算机网络和因特网什么是 Internet?具体构造的的角度服务角度网络结构 网络边缘网络核心电路交换分组交换概述排队时延和分组丢失转发表和路由选择协议按照有无网络层的连接 分组交换 VS 电路交换 接入网DSL 因特网接入电缆因特网接入光纤到户 FTTH无线接入网…

实现复杂树结构返回(不含子树), 并且结点间建立关联

&#x1f4a1; 一句话结&#xff1a; 实现传感器和深度及采集的数值动态对应&#xff0c;将不规则的数据转变成固定列头的一行行数据。 &#x1f511; 关键信息点&#xff1a; 通过传感器编号和深度将传感器对应的数值与时间建立关联。使用SpringBootMyBatis框架实现动态查询…

Nginx实现负载均衡与故障检查自动切换

创作灵感来源于个人项目的一个稳定性规划&#xff0c;单节点的项目稳定性方面可能有很大的缺漏&#xff0c;因此需要升级为多节点&#xff0c;保证服务故障后&#xff0c;依然有其他服务可用&#xff0c;不会给前端用户造成影响。 &#xff08;前面讲选型&#xff0c;想直接看…

亚马逊自养号测评环境搭建技巧:打造防关联底层环境的关键步骤

今天我们要聊的是完全由人工操作的自养号方法&#xff0c;相信有过相关经验的朋友们都清楚&#xff0c;在实现自养号的过程中&#xff0c;所使用的 IP 和浏览器究竟有哪些选择&#xff0c;以及可能会遇到哪些问题。 首先&#xff0c;我们来看看市场上现有的 IP 类型以及可能出现…

全网最全网络基础思维导图合集(38张)

计算机网络基础知识点多且杂&#xff0c;想要系统地学习&#xff0c;思维导图肯定是必不可少的。 今天整理了38张思维导图&#xff0c;帮助你轻松理清思路&#xff0c;快速掌握关键内容。建议你收藏起来慢慢看&#xff0c;在看过之后最好能重新动手画一画&#xff0c;让计算机…

如何获取一个城市或者一个区域的玫瑰风向图?

玫瑰风向图是一种直观展示风向和风速的图形工具&#xff0c;它在气象学、城市规划、农业等领域都有广泛的应用。那么&#xff0c;如何获取某个城市或某个区域的玫瑰风向图呢&#xff1f; 首先&#xff0c;我们可以借助互联网资源获取玫瑰风向图。现代网络技术发达&#xff0c;…

CentOS部署NFS

NFS服务端 部署NFS服务端 sudo yum install -y nfs-utils挂载目录 给 NFS 指定一个存储位置&#xff0c;也就是网络共享目录。一般来说&#xff0c;应该建立一个专门的 /data 目录&#xff0c;方便起见使用临时目录 /tmp/nfs&#xff1a; mkdir -p /tmp/nfs #修改权限 chmo…

vue使用海康的H5视频播放器开发包实时预览监控画面

使用原因 之前用海康的视频WEB插件实现过监控画面在前端页面的实时预览&#xff0c;但是会有两个问题&#xff1a; 1、该插件需要先进行安装&#xff0c;而且每次开机后也要重新启动该插件&#xff1b; 2、使用该插件很难更改其样式&#xff0c;只能使用其自带的窗口&#xff…

JavaSE——类和对象(二)~~封装

目录 一.封装 二.封装扩展之包 三.static成员 四. 代码块 五. 内部类&#xff08;重要&#xff09; 大家好呀&#xff0c;我是北纬&#xff0c;接着上节我们继续讲解Java中关于类和对象的相关知识&#xff0c;今天着重给大家介绍一下关于面向对象程序的特性之一——封装。…

【网络安全】网络安全协议的重要性

一.网络安全 1.什么是网络安全 网络安全&#xff08;Cyber Security&#xff09;是指网络系统的硬件、软件及其系统中的数据受到保护&#xff0c;不因偶然的或者恶意的原因而遭受到破坏、更改、泄露&#xff0c;系统连续可靠正常地运行&#xff0c;网络服务不中断。 2.网络安…