Example 1: Optimization

This example determines the minimum number of servers required to satisfy a service requirement that, at each time 1, 2, 3, the probability of having five or more entities in the buffer of a multiserver system is less than 5%.

Here is the familiar code to create the engine and specify the attributes:

from qplex import StandardMultiserver

engine = StandardMultiserver()
engine.number_of_arrivals_pmf = {2: 0.3, 3: 0.7}
engine.service_duration_pmf = {1: 0.6, 2: 0.3, 3: 0.1}

The number of servers attribute is not specified as it remains to be determined.

Since the maximum number of arrivals in any period is three and there are three periods, there can be at most nine arrivals in all. With five servers, it is impossible to have five or more entities in the buffer. As a result, at most five servers are needed to satisfy the service requirement.

The logic to find the minimum number of servers begins with an outer loop. Here is the pseudocode:

for each number of servers:
    determine whether the requirement is satisfied.

And here is the Python implementation, where it is assumed that a suitable function number_of_servers_satisfies_requirement has been defined:

for number_of_servers in range(1, 6):
    if number_of_servers_satisfies_requirement(number_of_servers):
        print('Number of servers required = ', number_of_servers)
        break

The function number_of_servers_satisfies_requirement itself also requires a loop. Here is the pseudocode:

restore the engine to its initial state.
for each time t = 1, 2, 3
    determine whether the number in system distribution satisfies the requirement.

And here is the Python implementation:

def number_of_servers_satisfies_requirement(number_of_servers):
    engine.restore()
    engine.number_of_servers = number_of_servers

    for t in range(3):
        engine.step()
        pmf = engine.get_number_of_entities_in_system_pmf()
        if not pmf_satisfies_requirement(pmf, number_of_servers):
            return False

    return True

Once again, the inner logic has been relegated to a function, in this case, pmf_satisfies_requirement. It calculates the requisite tail probability and if it is less than 0.05, then it returns True; otherwise it returns False. Here is the Python implementation:

def pmf_satisfies_requirement(pmf, number_of_servers):
    tail_prob = sum([pmf[z] for z in pmf if z >= number_of_servers+5])
    return tail_prob < 0.05

Here is the complete Python code presented in proper order:

from qplex import StandardMultiserver

def pmf_satisfies_requirement(pmf, number_of_servers):
    tail_prob = sum([pmf[z] for z in pmf if z >= number_of_servers+5])
    return tail_prob < 0.05

def number_of_servers_satisfies_requirement(number_of_servers):
    engine.restore()
    engine.number_of_servers = number_of_servers

    for t in range(3):
        engine.step()
        pmf = engine.get_number_of_entities_in_system_pmf()
        if not pmf_satisfies_requirement(pmf, number_of_servers):
            return False

    return True

engine = StandardMultiserver()
engine.number_of_arrivals_pmf = {2: 0.3, 3: 0.7}
engine.service_duration_pmf = {1: 0.6, 2: 0.3, 3: 0.1}
engine.mark()

for number_of_servers in range(1, 6):
    if number_of_servers_satisfies_requirement(number_of_servers):
        print('Number of servers required = ', number_of_servers)
        break

And here is the output:

Number of servers required = 3