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())