Esempio n. 1
0
def test_find_best_match():
    ab_pos = BloodType(BloodTypeLetter.AB, BloodTypePolarity.POS)
    o_neg = BloodType(BloodTypeLetter.O, BloodTypePolarity.NEG)
    wait_list = WaitList()

    patient1 = Patient('name', 'illness 1', OrganType.Pancreas,
                       ab_pos, 100, 1, wait_list)
    patient2 = Patient('name', 'illness 2', OrganType.Pancreas,
                       ab_pos, 250, 3, wait_list)
    patient3 = Patient('name', 'illness 3', OrganType.Pancreas,
                       o_neg, 400, 2, wait_list)
    patient4 = Patient('name', 'illness 4', OrganType.Heart,
                       ab_pos, 500, 2, wait_list)
    organ = Organ(OrganType.Pancreas, o_neg, 1)

    node1 = Node(1, adjacency_dict={2: {'weight': 10, 'status': True},
                                    3: {'weight': 25, 'status': True}})
    node2 = Node(2, adjacency_dict={3: {'weight': 35, 'status': True}})
    node3 = Node(3)
    test_net = Network({1: node1, 2: node2, 3: node3})
    weights, paths = Dijkstra.dijkstra(test_net, 1)

    patient = OrganAllocator.find_best_match(organ, wait_list, weights)
    assert patient is patient3
    assert len(wait_list.wait_list) is 4

    node1.adjacency_dict[3]['weight'] = 300
    node3.adjacency_dict[1]['weight'] = 300
    test_net.mark_node_inactive(2)
    wait_list.remove_patient(patient3)
    weights, paths = Dijkstra.dijkstra(test_net, 1)
    assert len(weights) is 2

    patient = OrganAllocator.find_best_match(organ, wait_list, weights)
    assert patient is patient1
    def allocate_organs(organ_list: OrganList, wait_list: WaitList,
                        network: Network) -> None:
        """
        Allocates organs from an OrganList to patients on a WaitList in a given Network.
        Organs are  allocated to the patient with the highest priority within a a suitable proximity.
        The proximity is considered suitable iff  (organ viability) - (cost of travel) >= 10

        :param OrganList organ_list: list of organs available for transplant
        :param WaitList wait_list: list of patients in need of transplant
        :param Network network: hospital network patients and organs are present in
        """
        # ANSI codes to emphasize output
        bold, reset = '\033[1m', '\033[0m'
        source, recipient = None, None

        for organ in organ_list.organ_list:
            if organ.origin_location is source:
                recipient = OrganAllocator.find_best_match(
                    organ, wait_list, dijkstra.weight)  # type: ignore
            else:
                source = organ.origin_location
                dijkstra = Dijkstra(network, source)
                recipient = OrganAllocator.find_best_match(
                    organ, wait_list, dijkstra.weight)

            if recipient:
                organ.move_organ(recipient.location,
                                 dijkstra.weight[recipient.location],
                                 dijkstra.shortest_path(recipient.location))
                wait_list.remove_patient(recipient)
                print(f'\n{bold}The following pair have been united:{reset}'
                      f'\n{recipient.__str__()}{organ.__str__()}')

            # organ is always removed (either matched, or exceeds max viability)
            organ_list.empty_list()
Esempio n. 3
0
    def generate_patients_to_list(graph: Network, n: int,
                                  wait_list: WaitList) -> None:
        """
        Generates N patients and add all generated patients to a WaitList


        :param Network graph: network where patients can be generated
        :param int n: number of patients to generate
        :param WaitList wait_list: list of patients to add generated patients to
        """
        wait_list.add_patients(PatientGenerator.generate_patients(graph, n))
def generate_random_graphs(path='.'):
    for x in range(1, 4):
        with shelve.open(join(path, f'random_networks{x}')) as db:
            db.clear()
            network = GraphBuilder.graph_builder(n=150, max_weight=25)

            patients = WaitList()
            PatientGenerator.generate_patients_to_list(graph=network,
                                                       n=300,
                                                       wait_list=patients)

            organs = OrganList()
            OrganGenerator.generate_organs_to_list(graph=network,
                                                   n=75,
                                                   organ_list=organs)

            hospital_network = network
            patient_network = SubnetworkGenerator.generate_subnetwork(
                network=hospital_network, collection=patients)
            organ_network = SubnetworkGenerator.generate_subnetwork(
                network=hospital_network, collection=organs)

            db[f'hospital_network{x}'] = hospital_network
            db[f'patient_network{x}'] = patient_network
            db[f'organ_network{x}'] = organ_network
Esempio n. 5
0
def test_allocate_organs():
    ab_pos = BloodType(BloodTypeLetter.AB, BloodTypePolarity.POS)
    o_neg = BloodType(BloodTypeLetter.O, BloodTypePolarity.NEG)
    organ_list = OrganList()

    organ1 = Organ(OrganType.Pancreas, ab_pos, 1, organ_list)
    organ2 = Organ(OrganType.Heart, o_neg, 1, organ_list)

    wait_list = WaitList()
    patient1 = Patient('name', 'illness 1', OrganType.Pancreas,
                       ab_pos, 100, 1, wait_list)
    patient2 = Patient('name', 'illness 2', OrganType.Pancreas,
                       o_neg, 200, 3, wait_list)
    patient3 = Patient('name', 'illness 3', OrganType.Heart,
                       ab_pos, 100, 2, wait_list)
    patient4 = Patient('name', 'illness 4', OrganType.Heart,
                       ab_pos, 50, 2, wait_list)

    node1 = Node(1, adjacency_dict={2: {'weight': 10, 'status': True},
                                    3: {'weight': 25, 'status': True}})
    node2 = Node(2, adjacency_dict={3: {'weight': 35, 'status': True}})
    node3 = Node(3)
    test_net = Network({1: node1, 2: node2, 3: node3})

    OrganAllocator.allocate_organs(organ_list, wait_list, test_net)
    assert len(organ_list.organ_list) is 0
    assert len(wait_list.wait_list) is 2
    assert patient2 in wait_list.wait_list
    assert patient4 in wait_list.wait_list
    def find_best_match(organ: Organ, wait_list: WaitList,
                        weights: Dict[int, float]) -> Optional[Patient]:
        """
        Finds the most optimal patient match for a given organ. The optimal match
        is the patient with the highest priority rating of compatible organ_need/blood_type
        who is within a tolerable distance (for organ viability)

        :param Organ organ: individual organ which is being matched with the optimal patient
        :param WaitList wait_list: list of patients in need of a transplant
        :param dict weights: cumulative weights of shortest paths from source node (organ location)
                                to all other nodes in the network
        :return: Patient representing the most optimal match
        """
        # ANSI codes to emphasize output
        bold_red, red, reset = '\033[31;1m', '\033[31m', '\033[0m'
        matches = wait_list.get_prioritized_patients(organ)

        # returns the patient with the highest priority within acceptable proximity
        while len(matches) != 0:
            patient = heapq._heappop_max(matches)  # type: ignore
            if organ.viability >= weights[patient.location] - 10:
                return patient

        # in the event there are no matches
        print(f'\n{bold_red}The following organ has no suitable matches:'
              f'\n{red}{organ.__str__()}{reset}')
        return None
Esempio n. 7
0
def reset_network():
    """
    Resets the network by clearing the organ list and wait list variables.
    This leaves an empty network to continue interacting with.
    """
    global organ_list
    global wait_list

    organ_list = OrganList()
    wait_list = WaitList()

    print(f'\n{ANSI_BOLD}The network has been reset. There are no '
          f'patients or organs remaining in the network.{ANSI_RESET}\n')
Esempio n. 8
0
def test_generate_patients_to_list():
    wait_list = WaitList()
    PatientGenerator.generate_patients_to_list(graph=test_net,
                                               n=n,
                                               wait_list=wait_list)

    assert len(wait_list.wait_list) is n
    for patient in wait_list.wait_list:
        assert patient.location in test_net.nodes()
        assert 0 <= patient.organ_needed.value <= 5
        assert 0 <= patient.blood_type.blood_type_letter.value <= 3
        assert 0 <= patient.blood_type.blood_type_polarity.value <= 1
        assert 0 <= patient.priority < 100 + n
        assert patient.location in test_net.nodes()
Esempio n. 9
0
def restart():
    """
    Clears all data from the system. This removes the existing network,
    wait list, and organ list.
    """
    global network
    global organ_list
    global wait_list

    network = None
    organ_list = OrganList()
    wait_list = WaitList()

    print(f'\n{ANSI_BOLD}The system has been reset. There is no network,'
          f' patients, or organs.{ANSI_RESET}\n')
Esempio n. 10
0
def build_network():
    """
    Builds a network passing console input as GraphBuilder parameters (N nodes).
    If a network already exists, a confirmation message verifies
    the user wants to clear the existing data.
    """
    global network
    global wait_list
    global organ_list

    if network:
        response = input(f'\nThere is already an existing network!\n'
                         f'Would you like to clear the network? '
                         f'(this will clear patient and organ lists as well)\n'
                         f'{ANSI_YELLOW}(y/n): {ANSI_RESET}')
        if response.lower() == 'y':
            wait_list = WaitList()
            organ_list = OrganList()
        elif response.lower() == 'n':
            print()
            return
        else:
            print(f'\n{ANSI_BOLD}Unrecognized selection. Returning to '
                  f'main menu.{ANSI_RESET}\n')
            return
    try:
        response = int(
            input(f'\nEnter the number of hospitals (nodes) '
                  f'you\'d like in the network: '))

        network = GraphBuilder.graph_builder(response)
    except ValueError:
        print(f'\n{ANSI_RED_BOLD}ValueError:{ANSI_RED} valid values '
              f'are ints >= 4{ANSI_RESET}\n')
        return

    # network has been generated
    response = input(f'\nA network has been built with {response} nodes. '
                     f'Would you like to print the network to the console?'
                     f'\n{ANSI_YELLOW}(y/n): {ANSI_RESET}')
    if response.lower() == 'y':
        print(network)
    elif response.lower() == 'n':
        print()
        return
    else:
        print(f'\n{ANSI_BOLD}Unrecognized selection. Returning to '
              f'main menu.\n{ANSI_RESET}')
Esempio n. 11
0
#               2: {'weight': 4, 'status': True}})
# node5 = Node(5, "E",
#              {1: {'weight': 1, 'status': True},
#               4: {'weight': 2, 'status': True}})
#
# net = Network({node1.node_id: node1,
#                node2.node_id: node2,
#                node3.node_id: node3,
#                node4.node_id: node4,
#                node5.node_id: node5})

# creates network
network = GraphBuilder.graph_builder(20)

# creates patient list
wait_list = WaitList()
PatientGenerator.generate_patients_to_list(network, 10, wait_list)
print(wait_list)

# creates organ list
organ_list = OrganList()
OrganGenerator.generate_organs_to_list(network, 10, organ_list)
print(organ_list)

# creates subnetworks for patients and organs
patient_network = SubnetworkGenerator.generate_subnetwork(network, wait_list)
organ_network = SubnetworkGenerator.generate_subnetwork(network, organ_list)

# generates NetworkX graphs
graph_nx = GraphConverter.convert_to_networkx(network)
patient_nx = GraphConverter.convert_to_networkx(patient_network)
Esempio n. 12
0
from network_simulator.GraphBuilder import GraphBuilder
from network_simulator.OrganAllocator import OrganAllocator
from network_simulator.OrganGenerator import OrganGenerator
from network_simulator.OrganList import OrganList
from network_simulator.PatientGenerator import PatientGenerator
from network_simulator.WaitList import WaitList

network, wait_list, organ_list = None, WaitList(), OrganList()
ANSI_YELLOW, ANSI_YELLOW_BOLD, ANSI_RED = '\033[33m', '\033[33;1m', '\033[31m'
ANSI_RED_BOLD, ANSI_BOLD, ANSI_RESET = '\033[31;1m', '\033[1m', '\033[0m'


def print_menu():
    """
    Prints menu options
    """
    print(
        f'{ANSI_YELLOW}Main Menu:{ANSI_RESET}\n'
        f'\t{ANSI_YELLOW}1 -{ANSI_RESET} Generate Network\n'
        f'\t{ANSI_YELLOW}2 -{ANSI_RESET} Generate Patients\n'
        f'\t{ANSI_YELLOW}3 -{ANSI_RESET} Harvest Organs (and allocate)\n'
        f'\t{ANSI_YELLOW}4 -{ANSI_RESET} Reset Network (clears list of patients/organs)\n'
        f'\t{ANSI_YELLOW}5 -{ANSI_RESET} Restart\n'
        f'\t{ANSI_YELLOW}0 -{ANSI_RESET} Exit\n')


def main_menu():
    """
    Control structure executes each action corresponding to menu items.
    Loops until user enters 0 to exit.
    """