Beispiel #1
0
def create_rate_constraint_violations(
    timeslot_length,
    alpha=0.15,
    delta=0.01756,
    eta0=0.00005,
    scale=12,
    coef_init=None,
    intercept_init=None,
    pessymistic_latency=0.5,
):
    if coef_init is None:
        coef_init = [[0.26]]

    if intercept_init is None:
        intercept_init = [-0.07*scale]

    # eta0 = 0.0002
    # eta0 = 0.0002

    rate_model = SGDRegressor(
        # loss='hinge',
        loss='squared_epsilon_insensitive',
        # loss='epsilon_insensitive',
        alpha=0,
        # shuffle=True,
        verbose=0,
        epsilon=0.2,
        learning_rate='constant',
        eta0=eta0,
        power_t=0.3,
        # fit_intercept=False,

        penalty='l2',
        max_iter=1000,
        tol=1e-3,
        shuffle=True,
        warm_start=False,
        average=False,
    )
    train_data = []
    params_history = []

    rate_model.eta0 = 1
    rate_model.fit(
        [[0], [1]], [intercept_init[0], 1*coef_init[0][0]+intercept_init[0]],
        coef_init=coef_init,
        intercept_init=intercept_init,
    )
    rate_model.eta0 = eta0
    # print(
    #     f'initial coef: {rate_model.coef_}, {rate_model.intercept_}'
    # )

    params_history.append(
        (0, rate_model.coef_[0], rate_model.intercept_[0])
    )

    def update_model(all_messages, t):
        window = messageset_to_window(all_messages, t-pessymistic_latency)
        without_sent = [
                m
                for m in window
                if m.t_rcv is not None
        ]

        if len(without_sent) == 0:
            return

        throughput = average_throughput(window)
        rate = average_rate(without_sent)
        X = [[throughput*scale]]
        Y = [rate*scale]
        train_data.append((throughput, rate))
        # print(
        #     f'Observing ({X}, {Y}) -> '
        #     f'new coef: {rate_model.coef_}, {rate_model.intercept_}'
        # )
        rate_model.partial_fit(X, Y)
        params_history.append(
            (t, rate_model.coef_[0], rate_model.intercept_[0])
        )

    def messageset_to_window(messageset, t):
        msgs = messageset.gen_after(t-timeslot_length)
        return [
            m
            for m in msgs
            if m.t_gen <= t
        ]

    def modeled_value(messageset, t):
        return modeled_window_value(messageset_to_window(messageset, t))

    def average_throughput(window):
        assert window[-1].t_gen - window[0].t_gen <= timeslot_length, window
        return sum([
            m.size*8/timeslot_length/10**6
            for m in window
        ])

    def modeled_window_value(window):
        throughput = average_throughput(window)
        a = rate_model.coef_[0]
        b = rate_model.intercept_[0]
        result = a*throughput*scale + b
        # result2 = rate_model.predict([[throughput*scale]])[0]
        return result/scale

    def _rate_constraint_violated(window):
        if modeled_window_value(window) <= alpha:
            return 0
        else:
            return 1

    def rate_constraint_violations(messageset, incremental=False):
        """
        Returns the number of times the rate constraint is violated.
        """
        if incremental:
            msgs = messageset.msgs_gen_after(
                messageset.message.t_gen - timeslot_length
            )
            return _rate_constraint_violated(tuple(msgs))

        else:
            msgs = messageset.all()
            result = 0
            window = deque()

            for m in msgs:
                window.append(m)
                while m.t_sent - window[0].t_sent > timeslot_length:
                    window.popleft()

                if _rate_constraint_violated(window):
                    result += 1

            return result

    def compute_value(messageset, t):
        return average_rate(messageset_to_window(messageset, t))

    def average_rate(window):
        # rates = [
        #     (m.size*8/10**6)/(m.t_rcv - m.t_gen)
        #     for m in window
        # ]

        # return sum(rates)/len(rates)
        avg_data_inflight = sum([
            m.size * (m.t_rcv - m.t_gen) * 8 / 10**6
            for m in window
        ])/timeslot_length
        avg_latency = sum([
            (m.t_rcv - m.t_gen)
            for m in window
        ])/len(window)
        return abs(avg_data_inflight/avg_latency - avg_data_inflight/delta)
        # return avg_data_inflight/0.01756

    rate_constraint_violations.compute_value = compute_value
    rate_constraint_violations.modeled_value = modeled_value
    rate_constraint_violations.update_model = update_model
    rate_constraint_violations.train_data = train_data
    rate_constraint_violations.model_params_history = params_history
    rate_constraint_violations.rate_model = rate_model

    rate_constraint_violations.messageset_to_window = messageset_to_window
    rate_constraint_violations.pessymistic_latency = pessymistic_latency
    rate_constraint_violations.average_rate = average_rate
    rate_constraint_violations.average_throughput = average_throughput
    return rate_constraint_violations