Добавил:
я зроблений з цукру Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
2
Добавлен:
09.12.2023
Размер:
5.65 Кб
Скачать
from math import pow
import pandas as pd
import matplotlib.pyplot as plt
from tabulate import tabulate


class Solver:
    def __init__(self, alpha, user_at_home, heat_cost, Tout, heat_energy):
        # Коэффициент важности дискомфорта пользователя.
        self.alpha = alpha
        # Массив булевых значений, когда пользователь присутствует дома.
        self.b = user_at_home.copy()
        # Кусочная функция стоимости отопления от кол-ва энергии.
        self.c = heat_cost.copy()
        # Массив значений температуры на улице в каждый час.
        self.Tout = Tout.copy()
        # Кол-во вырабатываемых джоулей в зависимости от режима.
        self.u = heat_energy.copy()
        self.W_cache = [{} for _ in self.b]
        self.dis = 0

    def w(self, alpha, is_at_home, current_T, heat_cost):
        """
        Возвращает выигрыш: сумму дискомфорта пользователя и стоимость
        режима работы.
        """
        return is_at_home * alpha * pow(18 - current_T, 2) + (1 - alpha) * heat_cost

    def phi(self, heat, current_T, Tout):
        """Возвращает новое состояние: температуру в доме."""
        return current_T + 0.5 * (heat - 0.2 * (current_T - Tout))

    def W(self, stage, state):

        # Если для текущего этапа и состояния была рассчитана ф-ция.
        if state in self.W_cache[stage]:
            return self.W_cache[stage][state]

        best_w = None
        best_u = None
        best_dis = None
        for ui in self.u:
            # Если этап последний, то учитываем, какая температура будет после него.
            if stage == 11:
                final_t = round(self.phi(ui, state, self.Tout[stage]), 1)
                wi = round(self.w(self.alpha, self.b[stage], final_t, self.c[ui]), 2)

            else:
                wi = round(self.w(self.alpha, self.b[stage], state, self.c[ui]) + \
                     self.W(stage + 1, round(self.phi(ui, state, self.Tout[stage]), 1))[0], 2)

            if best_w is None or wi < best_w:
                best_w = wi
                best_u = ui

        # Мемоизация
        self.W_cache[stage][state] = (best_w, best_u)
        return (best_w, best_u)

    def restore_optimal(self):
        # Массив режимов работы в каждый час.
        control = []
        # Массив температуры на начало каждого этапа.
        temperature = []
        # Начальная температура.
        state = 18
        for stage in range(len(self.b)):
            temperature.append(state)
            # Значение не персчитывается, так все они были записаны.
            # Лучший режим работы среди сохраненных находим по состоянию.
            u = self.W(stage, state)[1]
            control.append(u)
            state = round(self.phi(u, state, self.Tout[stage]), 1)
        return control, temperature, state

    def solve(self):
        return (self.W(0, 18)[0], *self.restore_optimal())


# Коэффициент важности дсикомфорта пользователя.
alpha = 0.8
# Массив булевых значений, когда пользователь присутствует дома.
bi = [0 if i < 6 else 1 for i in range(12)]
# Кусочная функция стоимости отопления от кол-ва энергии.
c = {0: 0, 2: 12, 4: 25, 6: 43, 8: 62, 10: 83}
# Массив значений температуры на улице в каждый час.
Tout = [-14, -13, -13, -12, -12, -11, -11, -10, -10, -9, -9, -8]
# Кол-во вырабатываемых джоулей в зависимости от режима.
u = [0, 2, 4, 6, 8, 10]

s = Solver(alpha, bi, c, Tout, u)
W, U, T, final_T = s.solve()


# Вывод резульатов.
columns = [bi, T, U]
row_names = ['Присутствие пользователя', 'Температура', 'Режим работы']
columns = [list(i) for i in zip(*columns)]
column_names = [list(range(1, 13))]

data = dict(zip(*column_names, columns))
df = pd.DataFrame(data, index=row_names)
print(tabulate(df, headers='keys', tablefmt='psql'))

cost = sum(map(lambda x: c[x], U))

print(f"Значение alpha: {alpha};")
print(f"Значение целевой функции: {W};")
print(f"Температура в конце 12-го часа: {final_T};")
print(f"Стоимость отопления: {cost} ДЕ.")


# Анализ чувствительности:
alpha = [i/100 for i in range(1, 101)]
costs = []
w = []
for a in alpha:
    s = Solver(a, bi, c, Tout, u)
    W, U, T, final_T = s.solve()
    cost = sum(map(lambda x: c[x], U))
    w.append(W)
    costs.append(cost)

plt.plot(alpha, costs, 'ro--')
plt.plot(alpha, w, 'go--')
plt.title('Зависимость стоимости и целевой функции от коэффициента значимости', fontsize=20, fontname='Times New Roman')
plt.xlabel('Альфа', fontsize=20)
plt.ylabel('Y', fontsize=20)
plt.show()
Соседние файлы в папке Практическая работа №3