摘要:
民以食为天,合理的饮食是身体健康的基础。科学的控制摄入食物的比例可以健康的减肥。实际的饮食计划中既要考虑较低的热量摄入,还要考虑较高的满足感和饱腹感,并且营养要均衡。本文采用多目标加权、分优先级的方法将多目标优化问题转化为多个线性规划问题并利用scipy求解。最终得出一份综合多个目标、符合已知约束条件的饮食表。
一:提出问题
1.1、问题描述
在不同的时候需要调整自己的饮食计划,包括增肌和减脂。
对饮食计划进行建模,要求:
- (1)只考虑饮食,不考虑运动,假设基础代谢为常数。
- (2)只考虑食物中的主要成分:蛋白质,脂肪,碳水化合物三种主要热量来源,考虑维生素,钠离子两种微量元素,不考虑其它微量元素。
- (3)饮食计划要综合考虑:热量摄入、饱腹感(GI值)、满足感(高脂肪高糖满足感高)。
- (4)考虑营养均衡。单种营养素的范围,脂肪中的饱和脂肪与不饱和脂肪,碳水化合物中膳食纤维。(不饱和脂肪和膳食纤维的热量贡献非常小)
- (5)假设食物可以由营养素线性表出,没有损失
1.2、问题背景
中国营养学会2000年提出中国居民膳食能量参考摄入量指出,成年男性轻、中体力劳动者每日需要能量为2400-2700kcal;女性轻、中体力劳动者每日需要能量为2100-2300kcal。婴儿、儿童和青少年、孕妇和乳母、老年人各自的生理特点不同,能量需要也不尽相同。如果想要更精确的得出自己每天摄入的热量,可以参考基础代谢率公示(摄入量大于这个数字):
- 女: BMR = 655 + ( 9.6 x 体重kg ) + ( 1.8 x 身高cm ) - ( 4.7 x 年龄years )
- 男: BMR = 660 + ( 13.7 x 体重kg ) + ( 5 x 身高cm ) - ( 6.8 x 年龄years )
其中蛋白质摄取量应为人体每日所需热量的10%~15%;碳水化合物摄取量应不少于人体每日所需热量的 55%;脂肪的摄取量应不超过每日所需热量的30%。此外,每天摄取的盐不应超过6克,膳食纤维每天的摄取量应不少于16克。
人类生存需要能量,并从食物中获取该能量。食物中的卡路里含量是该食品产生多少潜在能量的量度标准。食物一般由碳水化合物、蛋白质、脂肪这三种物质组成。因此只要知道食物中这三种物质的含量,就可以知道食物含多少卡路里或多少能量。
- 1、碳水化合物产生热能 = 4 千卡(4大卡)/克
- 2、蛋白质产生热量 = 4 千卡(4大卡)/克
- 3、脂肪产生热量 = 9 千卡(9大卡)/克
维生素C支持人体的保卫系统和缔结组织。它在运动时会随汗液排出体外,必须及时补充。维生素E保护人身不受外来恶劣环境的侵害,尤其是过度劳累和紧张,环境破坏及训练等对人体的侵害。同时促进肌肉对氧的吸收。要满足人体对维生素的需要,只有通过食用富含维生素的新鲜食物,如水果、蔬菜和全麦制品。对于那些平时维生素摄入不足,膳食不平衡的人,可服用维生素补剂。成人一天需要摄入的各种维生素的量如下:维生素A原或前维生素A 2毫克; 维生素B1 1.4毫克; 维生素B2 1.6毫克; 维生素B6 2毫克;维生素B12 1微克; 维生素C 60毫克
; 维生素E 10毫克; 尼克酸 18毫克; 叶酸 200微克; 泛酸 6毫克。
人体内钠在一般情况下不易缺乏、但在某些情况下,如禁食、少食,膳食钠限制过严而摄入非常低时,或在高温、重体力劳动、过量出汗、肠胃疾病、反复呕吐、腹泻使钠过量排出而丢失时,或某些疾病,如艾迪生病引起肾不能有效保留钠时,胃肠外营养缺钠或低钠时,利尿剂的使用而抑制肾小管重吸收钠时均可引起钠缺乏。钠的缺乏在早期症状不明显,倦怠、淡漠、无神、甚至起立时昏倒。失钠达0.5g/kg体重以上时,可出现恶心、呕吐、血压下降、痛性吉尔痉挛,尿中无氯化物检出。18岁以后建议的钠摄入量为2000毫克
。
综合上述材料得出以下表格:
蛋白质 脂肪(饱和脂肪) 碳水化合物(除膳食纤维) 维生素(VC) 钠离子
热量占比 %10-%15 <30% >55% 0 0
推荐摄入量 热量4 热量9 热量*4 60mg 2000mg
饱腹感 2 1 2 0 0
满足感 1 2 2 0 0
中国居民平衡膳食宝塔是根据中国居民膳食指南结合中国居民的膳食结构特点设计的。它把平衡膳食的原则转化成各类食物的重量,并以直观的宝塔形式表现出来,便于群众理解和在日常生活中实行。
平衡膳食宝塔提出了一个营养上比较理想的膳食模式。它所建议的食物量,特别是奶类和豆类食物的量可能与大多数人当前的实际膳食还有一定距离,对某些贫困地区来讲可能距离还很远,但为了改善中国居民的膳食营养状况,这是不可缺的。应把它看作是一个奋斗目标,努力争取,逐步达到。
二:做出假设
题目中已有的假设:
- 只考虑饮食,不考虑运动,假设基础代谢为常数。
- 只考虑食物中的主要成分:蛋白质,脂肪,碳水化合物三种主要热量来源。
- 考虑维生素,钠离子两种微量元素,不考虑其它微量元素。
- 假设食物可以由营养素线性表出,没有损失
关于代谢
- 人一天的基础代谢可由BMR公式得出
- 基础代谢影响因素只考虑年龄、性别、身高和体重
关于营养素:
- 不饱和脂肪产生的热量忽略不计
- 膳食纤维产生的热量忽略不计
- 维生素只考虑维生素C一种,其他微量的忽略不计。
- 热量、饱腹感、满足感均只来源于蛋白质、脂肪、碳水化合物三类物质
- 摄入每克蛋白质、脂肪、碳水化合物得到的热量为4、9、4 kj
- 摄入每克蛋白质、脂肪、碳水化合物得到的饱腹感比例为2:1:2
- 摄入每克蛋白质、脂肪、碳水化合物得到的满足感比例为1:2:2
关于食物:
- 食物只考虑列出的11种
- 不考虑同类食物之间的差异
- 食物中含有的营养素以表格中给出的为准
三:建模过程
3.1、总体思路
本题要在已知的约束条件下,摄入最少的热量,其次是要获得较高的满足感和饱腹感。
分析题目可知,本题是多目标优化问题,涉及到三个目标:摄入最少的热量与获得较高的满足感和饱腹感,并且要满足已知的约束条件。
这里对三个目标的处理方法是:给三个目标分优先级依次处理,上一次处理的结果施加一定的权值作为下一次的约束条件。这样就把此多目标优化问题转化成了多个线性规划问题,然后求解。
但是由于三者的数值不具有很强的可比性,对三者赋予的权值难以确定,所以这里尝试各种比例并做出变化图,最终确定一个符合要求的权值比例并得出结果。
3.2、数据处理
首先根据人物信息(性别、年龄、身高、体重)计算出BMR数值,该值作为静态的基础代谢值。
然后打开数据文件diet_plan.csv,从中读取所有的食物中各种营养素的占比(百分比),以小数的形式给出,读取的结果存到字典里面,字典名是食物名,字典的键是营养素名,键对应的值是该营养素在该食物中的占比(例如:milk[protain]=k,表示每克牛奶中有k克的蛋白质)。这里是动态的读取,即在运行程序前没有指定食物的名称也就是没有指定字典的名称,实现的方法是利用locals获取当前局部变量然后修改(用eval函数)。
现在就获取到了所有食物的列表和一系列储存着食物中各营养素比例的字典。
3.3、建模
决策变量:
这里的决策变量是各种食物每天的摄入量
目标函数:
这里的目标函数有三个:最小化热量、最大化GI、最大化满足感
- 热量:
热量来源有蛋白质、脂肪、碳水三个部分。
计算公式是每克蛋白质、脂肪、碳水产能4、9、4kj - 饱腹感(GI)与满足感:
饱腹感与满足感同样来源于蛋白质、脂肪、碳水三个部分。
查阅资料可知蛋白质、碳水饱腹感强于脂肪,所以自定义三者单位质量饱腹感比例为2:1:1。
而脂肪与碳水的满足感要高于蛋白质,所以自定义三者单位质量满足感比例为1:2:2。
这里直接用摄入食物的质量乘以比例,得到的数值没有具体含义,数值的变化趋势才有意义,后面作图时对其做了一定的放大方便将三者放在一起观察。
1.# 三个目标函数
2.# min all_heat
3.c_heat = np.sum([vec_protain * 4, vec_fat * 9, vec_sugar * 4], axis=0)
4.# max gi
5.c_gi = np.sum([vec_protain * 2, vec_fat * 1, vec_sugar * 2], axis=0)
6.c_gi *= -1.5 # 符号是由于目标是最大化,数值是用来放大方便再图上观察(数值无意义、变化与比例才有意义)
7.# max satisfaction
8.c_sat = np.sum([vec_protain * 1, vec_fat * 2, vec_sugar * 2], axis=0)
9.c_sat *= -1.8 # 同上
约束条件:
1.摄入的热量要高于BMR
2.蛋白质摄取量应为人体每日所需热量的10%~15%;
3.碳水化合物摄取量应不少于人体每日所需热量的 55%;
4.脂肪的摄取量应不超过每日所需热量的30%。
5.维生素摄入60mg左右
6.钠离子摄入2000mg左右
# 约束条件,A[i]*x[i] < b[i]
A = [vec_protain * 4, -4 * vec_protain, vec_fat * 9, -9 * vec_fat, -4 * vec_sugar, 4 * vec_sugar, vec_vita, -1 * vec_vita, vec_na, -1 * vec_na, -1 * c_heat]
b = [0.15 * BMR, -0.1 * BMR, 0.3 * BMR, 0.1 * BMR, -0.55 * BMR, 0.8 * BMR, 8.8, -7.2, 7, -5, -1 * BMR]
3.4、Python求解
这里用SciPy.linprog求解,该模块标准形式如下:
这里对三个目标的处理方法是:给三个目标分优先级依次处理,上一次处理的结果施加一定的权值作为下一次的约束条件。这样就把此多目标优化问题转化成了多个线性规划问题,然后求解。但是由于三者的数值不具有很强的可比性,对三者赋予的权值难以确定,所以这里尝试各种比例并做出变化图,最终确定一个符合要求的权值比例并得出结果。
低热量、高GI、高满足感三者占比为1:i:j。其中ij均以step为步长从beg增长到end。首先按照初始约束计算优先级最低的满足感,然后依据其算得的结果拓展约束条件(后续得到的满足感不低于此满足感i),然后再计算优先级中等的饱腹感,再依据其算得的结果拓展约束条件(后续得到的饱腹感不低于此饱腹感j),最后根据此时的约束条件计算优先级最高的热量摄入。
通过这样的方法就把几种目标函数以不同的权值组合在一起,结果以3D图片的形式展示出来(见下图,xy分别为占比,z轴对于三个目标函数的度量),并把计算过程中的数据储存在data.txt中,运算过程中如果没有正确的规划出方案,那么这一次的方案就取上一次的结果,并且写入错误日志log.txt中。
1.for i in np.arange(beg, end, step):
2. for j in np.arange(beg, end, step):
3. A = [vec_protain * 4, -4 * vec_protain, vec_fat * 9, -9 * vec_fat, -4 * vec_sugar, 4 * vec_sugar, vec_vita, -1 * vec_vita, vec_na, -1 * vec_na, -1