input_data = [["Продукт", "Идентификатор", "GHGE, кг на 100 гр.", "Популярность", "Цена, руб. за 100 гр.", "Потребление в день., гр.",\
"Энергетическая ценность, ккал / 100гр", "Энергетическая ценность, белки / 100гр", "Энергетическая ценность, жиры / 100гр",\
"Энергетическая ценность, углеводы / 100гр"],
["Картофель", "11831", 0.15, 1, 2.9, 112, 76, 2, 0.4, 16.1],
["Хлеб", "18060", 0.09, 1, 4.77, 90, 214, 6.9, 1.2, 43.2],
["Яйца", "01129", 0.27, 0.95, 74.7, 120, 157, 12.7, 10.9, 0.7],
["Фрукты", "09003", 0.07, 0.8, 8.1, 100, 50, 1, 0.2, 20],
["Печенье", "18204", 0.14, 0.8, 30, 53, 410, 8.0, 9.5, 72.0],
["Злаки", "08144", 0.12, 0.75, 15, 0, 342, 12.3, 6.1, 59.5],
["Овощи", "11894", 0.16, 0.78, 30, 143, 32, 1.3, 0.1, 6.9],
["Масло", "01001", 0.22, 0.8, 106, 20, 610, 1.0, 67.0, 1.6],
["Сыр", "01018", 1.19, 0.75, 56, 154, 352, 26.0, 26.8, 0.0],
["Молоко", "01291", 0.13, 0.85, 7.2, 378, 58, 2.8, 3.2, 4.7],
["Орехи", "12135", 0.21, 0.65, 125, 15, 500, 15.0, 40.0, 20.0],
["Рыба", "15237", 0.77, 0.8, 61, 0, 112, 16.0, 5.3, 0.0],
["Мясо", "13317", 0.65, 0.9, 53, 317, 187, 18.9, 12.4, 0.0]]
import pandas as pd
pd.DataFrame(input_data[1:], columns=input_data[0])
import numpy as np
from cvxopt.modeling import variable, op, dot, sum
from cvxopt import matrix, mul, spmatrix
input_data_frame = pd.DataFrame(input_data[1:], columns=input_data[0])
consume = list(input_data_frame.loc[:, "Потребление в день., гр."])
favorite = list(input_data_frame.loc[:, "Популярность"])
energy_kkal = list(input_data_frame.loc[:, "Энергетическая ценность, ккал / 100гр"])
energy_fat = list(input_data_frame.loc[:, "Энергетическая ценность, жиры / 100гр"])
energy_prot = list(input_data_frame.loc[:, "Энергетическая ценность, белки / 100гр"])
energy_carb = list(input_data_frame.loc[:, "Энергетическая ценность, углеводы / 100гр"])
pollution = list(input_data_frame.loc[:, "GHGE, кг на 100 гр."])
price = list(input_data_frame.loc[:, "Цена, руб. за 100 гр."])
x = variable(len(consume), "x")
# коофиценты приведенные в удобный для работы формат
consume_var = matrix(consume, tc='d')
favorite = np.array(favorite)
favorite = (favorite - min(favorite)) / (max(favorite) - min(favorite)) # нормализация
avg = (sum(favorite) / len(favorite)) # порог популярности
pop_fav_ind = [i for i, x in enumerate(favorite) if x < avg]
unpop_fav_ind = [i for i, x in enumerate(favorite) if x >= avg]
pop_favorite_cof = -(1 - matrix(favorite, tc='d') - avg) * 1.5
unpop_favorite_cof = (1 - avg + 0.05 - matrix(favorite, tc='d')) * 1.5
pop_favorite_cof[pop_fav_ind] = 0
unpop_favorite_cof[unpop_fav_ind] = 0
pop_favorite_cof = spmatrix(pop_favorite_cof, range(13), range(13))
unpop_favorite_cof = spmatrix(unpop_favorite_cof, range(13), range(13))
energy_kkal_cof = matrix(energy_kkal, tc='d') * 0.01
energy_kkal_cof = spmatrix(energy_kkal_cof, range(13), range(13))
energy_fat_cof = matrix(energy_fat, tc='d') * 0.01
energy_fat_cof = spmatrix(energy_fat_cof, range(13), range(13))
energy_prot_cof = matrix(energy_prot, tc='d') * 0.01
energy_prot_cof = spmatrix(energy_prot_cof, range(13), range(13))
energy_carb_cof = matrix(energy_carb, tc='d') * 0.01
energy_carb_cof = spmatrix(energy_carb_cof, range(13), range(13))
pollution_cof = matrix(pollution, tc='d') * 0.01
pollution_cof = spmatrix(pollution_cof, range(13), range(13))
price_cof = matrix(price, tc='d') * 0.01
price_cof = spmatrix(price_cof, range(13), range(13))
# функции для подсчета сумарных характеристик в зависимости от х
energy_kkal_func = sum(energy_kkal_cof * x)
energy_prot_func = sum(energy_prot_cof * x)
energy_fat_func = sum(energy_fat_cof * x)
energy_carb_func = sum(energy_carb_cof * x)
pollution_func = sum(pollution_cof * x)
money_func = sum(price_cof * x)
# ограничения
cnstr1 = (energy_kkal_func >= 3700)
cnstr2 = (energy_prot_func >= 102)
cnstr3 = (energy_fat_func >= 136)
cnstr4 = (energy_carb_func >= 518)
cnstr5 = (x >= 0)
cnstr6 = (pollution_func <= 1.8)
cnstr7 = (money_func <= (7500 / 30))
# другие ограничения для анализа чувствиельности
cnstr7_2 = (money_func <= (15000 / 30))
cnstr6_2 = (pollution_func <= 3.6)
# вывод используемых коэффицентов для штрафных функций
disp_data = [list(input_data_frame.loc[:, "Продукт"]), list(map(lambda x: round(x, 2), pop_favorite_cof)),
list(map(lambda x: round(x, 2), unpop_favorite_cof)),
list(map(lambda x: round(x, 2), favorite)), list(input_data_frame.loc[:, "Популярность"])]
disp_data = np.array(disp_data).transpose()
disp_headers = ["Проудкты", "Коэффицент в штрафной функции для популярных", "Коэффицент в штрафной функции для непопулярных", \
"Нормализованное знчаение популярности", "Старое значение популярности"]
temp_df = pd.DataFrame(disp_data, columns=disp_headers)
display(temp_df)
# целевая функция для оптимизации
main_func = sum(abs((x - consume_var)))
# функции штрафа
penalty_func_pop = sum(pop_favorite_cof * (consume_var - x))
penalty_func_unpop = sum(unpop_favorite_cof * (x - consume_var))
problem_1 = op(main_func + penalty_func_pop + penalty_func_unpop, [cnstr1, cnstr2, cnstr3, cnstr4, cnstr5]) # ограничения только по питательным, за 7500 невозможно
problem_2 = op(main_func + penalty_func_pop + penalty_func_unpop, [cnstr1, cnstr5, cnstr6, cnstr7]) # ограничения по питательным (ккал только) и выбросу
problem_2_2 = op(main_func + penalty_func_pop + penalty_func_unpop, [cnstr1, cnstr5, cnstr6_2, cnstr7]) # увелчиен порог выбросов в двое
problem_2_3 = op(main_func + penalty_func_pop + penalty_func_unpop, [cnstr1, cnstr5, cnstr6, cnstr7_2]) # увелчиен обьем денег на месяц в двое
print("ограничения только по питательным")
problem_1.solve()
problem_1_vals = x.value
print("ограничения по питательным и выбросу")
problem_2.solve()
problem_2_vals = x.value
print("для анализа чувствительности")
problem_2_2.solve()
problem_2_2_vals = x.value
print("для анализа чувствительности")
problem_2_3.solve()
problem_2_3_vals = x.value
print("только по питательным")
input_data_frame.loc[:, "Потребление в день., гр."] = [f"{consume[i]} -> {int(problem_1_vals[i])}" for i in range(len(consume))]
display(input_data_frame)
x.value = problem_1_vals
print("Ккал в день", energy_kkal_func.value()[0])
print("Загрязнение в день", pollution_func.value()[0])
print("Денег в месяц", money_func.value()[0] * 30)
print("Белков в день", energy_prot_func.value()[0])
print("Жиров в день", energy_fat_func.value()[0])
print("Углеводов в день", energy_carb_func.value()[0])
print("Значение целевой функции", main_func.value())
print("по питательным и выбросу")
input_data_frame.loc[:, "Потребление в день., гр."] = [f"{consume[i]} -> {int(problem_2_vals[i])}" for i in range(len(consume))]
display(input_data_frame)
x.value = problem_2_vals
print("Ккал в день", energy_kkal_func.value()[0])
print("Загрязнение в день", pollution_func.value()[0])
print("Денег в месяц", money_func.value()[0] * 30)
print("Белков в день", energy_prot_func.value()[0])
print("Жиров в день", energy_fat_func.value()[0])
print("Углеводов в день", energy_carb_func.value()[0])
print("Значение целевой функции", main_func.value())
print("для анализа чувствительности к порогу выбросов")
input_data_frame.loc[:, "Потребление в день., гр."] = [f"{consume[i]} -> {int(problem_2_2_vals[i])}" for i in range(len(consume))]
display(input_data_frame)
x.value = problem_2_2_vals
print("Ккал в день", energy_kkal_func.value()[0])
print("Загрязнение в день", pollution_func.value()[0])
print("Денег в месяц", money_func.value()[0] * 30)
print("Белков в день", energy_prot_func.value()[0])
print("Жиров в день", energy_fat_func.value()[0])
print("Углеводов в день", energy_carb_func.value()[0])
print("Значение целевой функции", main_func.value())
print("для анализа чувствительности к обьему денег на месяц")
input_data_frame.loc[:, "Потребление в день., гр."] = [f"{consume[i]} -> {int(problem_2_3_vals[i])}" for i in range(len(consume))]
display(input_data_frame)
x.value = problem_2_3_vals
print("Ккал в день", energy_kkal_func.value()[0])
print("Загрязнение в день", pollution_func.value()[0])
print("Денег в месяц", money_func.value()[0] * 30)
print("Белков в день", energy_prot_func.value()[0])
print("Жиров в день", energy_fat_func.value()[0])
print("Углеводов в день", energy_carb_func.value()[0])
print("Значение целевой функции", main_func.value())