def test_get_satisfied_demand():
    drained_amount = np.array([1, 2, 3, 4, 5])[:, None]
    demand_id = [0, 3]

    satisfied_demand = ClosedLoopCRW.get_satisfied_demand(
        drained_amount, demand_id)
    assert satisfied_demand == {0: 1, 3: 4}
def test_get_activity_supply_resource_association_action_belongs_to_two_resources(
):
    supply_nodes = [(0, 1)]
    constituency_matrix = np.array([[1, 1], [0, 1]])
    with pytest.raises(AssertionError):
        _, _ = ClosedLoopCRW.get_activity_supply_resource_association(
            supply_nodes, constituency_matrix)
def build_closed_loop_single_station_demand_model(
        initial_state=np.zeros((3, 1)), toa=100):
    ind_surplus_buffers = [1]
    demand_to_supplier_routes = {2: (2, toa)}
    job_gen_seed = 42
    mu = 3
    mud = 3
    mus = 3
    alpha = 2
    cost_per_buffer = np.array([[1], [2], [5]])
    demand_rate = np.array([[0], [0], [alpha]])
    buffer_processing_matrix = np.array([[-mu, 0, mus], [mu, -mud, 0],
                                         [0, -mud, 0]])
    job_generator = DeterministicDiscreteReviewJobGenerator(
        demand_rate,
        buffer_processing_matrix,
        job_gen_seed,
        sim_time_interval=1)
    constituency_matrix = np.eye(3)
    state_initialiser = DeterministicCRWStateInitialiser(initial_state)
    cl_env = ClosedLoopCRW(demand_to_supplier_routes, ind_surplus_buffers,
                           cost_per_buffer,
                           np.ones_like(demand_rate) * np.inf,
                           constituency_matrix, job_generator,
                           state_initialiser)
    return cl_env
def build_closed_loop_env_2_demand_buffers(demand_to_supplier_routes,
                                           constituency_matrix,
                                           initial_state=np.zeros((5, 1))):
    ind_surplus_buffers = [1, 3]
    job_gen_seed = 42
    mu = 1.5
    mud = 3
    mus = 1.5
    alpha = 0.95
    cost_per_buffer = np.array([[1], [2], [5], [3], [8]])
    demand_rate = np.array([[0], [0], [alpha], [0], [alpha]])
    buffer_processing_matrix = np.array([[-mu, -mu / 3, 0, mus, 0, 0],
                                         [2 * mu / 3, 0, -mud, 0, 0, 0],
                                         [0, 0, -mud, 0, 0, 0],
                                         [mu / 3, mu / 3, 0, 0, -mud, mus / 3],
                                         [0, 0, 0, 0, -mud, 0]])
    job_generator = ScaledBernoulliServicesPoissonArrivalsGenerator(
        demand_rate, buffer_processing_matrix, job_gen_seed=job_gen_seed)
    state_initialiser = DeterministicCRWStateInitialiser(initial_state)
    cl_env = ClosedLoopCRW(demand_to_supplier_routes, ind_surplus_buffers,
                           cost_per_buffer,
                           np.ones_like(demand_rate) * np.inf,
                           constituency_matrix, job_generator,
                           state_initialiser)
    return cl_env
def test_is_demand_to_supplier_routes_consistent_with_job_generator_envs(
        supply_ids, demand_ids, env_class):
    env = env_class()
    assert ClosedLoopCRW.is_demand_to_supplier_routes_consistent_with_job_generator(
        supply_ids, demand_ids,
        env.constituency_matrix, env.job_generator.supply_nodes,
        env.job_generator.demand_nodes.values())
def test_get_activity_supply_resource_association_two_resources():
    supply_nodes = [(0, 1), (1, 2), (2, 0)]
    constituency_matrix = np.array([[1, 1, 0], [0, 0, 1]])
    activity_to_resource, resource_to_activity = \
        ClosedLoopCRW.get_activity_supply_resource_association(
            supply_nodes,
            constituency_matrix
        )
    assert activity_to_resource == {0: 0, 1: 0, 2: 1}
    assert resource_to_activity == {0: [0, 1], 1: [2]}
def test_get_activity_supply_resource_association_only_one_resource():
    supply_nodes = [(0, 1), (1, 2)]
    constituency_matrix = np.array([[0, 1, 1], [1, 0, 0]])
    activity_to_resource, resource_to_activity = \
        ClosedLoopCRW.get_activity_supply_resource_association(
            supply_nodes,
            constituency_matrix
        )
    assert activity_to_resource == {1: 0, 2: 0}
    assert resource_to_activity == {0: [1, 2]}
def test_get_activity_supply_resource_association_eye():
    supply_nodes = [(0, 1), (1, 2)]
    constituency_matrix = np.eye(4)
    activity_to_resource, resource_to_activity = \
        ClosedLoopCRW.get_activity_supply_resource_association(
            supply_nodes,
            constituency_matrix
        )
    assert activity_to_resource == {1: 1, 2: 2}
    assert resource_to_activity == {1: [1], 2: [2]}
def test_is_supply_ids_consistent_with_job_generator_false():
    supply_ids = [2, 3]  # It should be [2, 4]
    demand_to_supplier_routes = {2: (2, 100), 4: (4, 300)}
    constituency_matrix = np.array([[1, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0],
                                    [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0],
                                    [0, 0, 0, 0, 0, 1]])
    env = build_closed_loop_env_2_demand_buffers(demand_to_supplier_routes,
                                                 constituency_matrix)
    assert not ClosedLoopCRW.is_supply_ids_consistent_with_job_generator(
        supply_ids, env.job_generator.supply_nodes, env.constituency_matrix)
def test_get_supply_and_demand_ids_repeated_ids():
    demand = (0, 1, 2, 3, 4)
    supply = (10, 11, 10, 11, 12)
    toa = (20, 21, 20, 21, 22)
    demand_to_supplier_routes = {
        demand[i]: (supply[i], toa[i])
        for i in range(len(demand))
    }

    supply_id, demand_id = ClosedLoopCRW.get_supply_and_demand_ids(
        demand_to_supplier_routes)
    assert supply_id == [10, 11, 12]
    assert demand_id == list(demand)
def test_get_supply_and_demand_ids():
    demand = (0, 1, 2, 3, 4, 5, 6, 7)
    supply = (10, 11, 12, 13, 14, 15, 16, 17)
    toa = (20, 21, 22, 23, 24, 25, 26, 27)
    demand_to_supplier_routes = {
        demand[i]: (supply[i], toa[i])
        for i in range(8)
    }

    supply_id, demand_id = ClosedLoopCRW.get_supply_and_demand_ids(
        demand_to_supplier_routes)
    assert supply_id == list(supply)
    assert demand_id == list(demand)
def test_are_demand_ids_unique_false():
    demand_id = [0, 0, 1, 2]
    assert not ClosedLoopCRW.are_demand_ids_unique(demand_id)
def test_are_demand_ids_unique():
    demand_id = list(range(4))
    assert ClosedLoopCRW.are_demand_ids_unique(demand_id)
def test_get_supply_activity_to_buffer_association_multiple_supply_activities(
):
    supply_nodes = [(0, 2), (1, 3)]
    activity_to_buffer = ClosedLoopCRW.get_supply_activity_to_buffer_association(
        supply_nodes)
    assert activity_to_buffer == {2: 0, 3: 1}
def test_get_supply_activity_to_buffer_association_only_one_supply_activity():
    supply_nodes = [(0, 2)]
    activity_to_buffer = ClosedLoopCRW.get_supply_activity_to_buffer_association(
        supply_nodes)
    assert activity_to_buffer == {2: 0}
def test_initialise_supply_buffers():
    supply_id = [0, 11]
    supply_buf = ClosedLoopCRW.initialise_supply_buffers(supply_id)
    assert supply_buf == {0: 0, 11: 0}