Project: s41467-025-60175-9 | Function: dijkstra_algorithm (python)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Implementation of Dijkstra's algorithm to find shortest paths between nodes in a weighted graph for optimal amplicon scheme design. Takes a graph and start node, returns previous nodes and shortest paths using priority queue.

**KEY TERMS:** {
  "shortest_path": "lowest penalty path",
  "current_distance": "cumulative penalty",
  "graph.get_neighbors": "connected amplicons",
  "heapq": "priority queue optimization"
}

**CONTEXT CODE:**     """
    # connect amplicons if they sufficiently overlap because:
    # ... the start of next amplicon lies in the second half of the prior amplicon
    if next_amplicon["LEFT"][1] < current_amplicon["LEFT"][1] + current_amplicon["length"] / 2:
        return False
    # ... the stop of the left primer of the next amplicon does not lie in the minimum amplicon insert
    if next_amplicon["LEFT"][2] > current_amplicon["RIGHT"][1] - min_overlap:
        return False
    # ... half of the next amplicon does not overlap with the previous amplicon --> enough space for a
    # further amplicon that lies in the second half next amplicon and cannot overlap with a primer of the
    # current amplicon
    if next_amplicon["RIGHT"][2] <= current_amplicon["RIGHT"][2] + next_amplicon["length"] / 2:
        return False

    return True


def create_amplicon_graph(amplicons, min_overlap):
    """
    creates the amplicon graph.
    """
    # ini graph and vertices
    amplicon_graph = {}
    nodes = []

    for current_amplicon in amplicons:
        # remember all vertices
        amplicon_id = current_amplicon["id"]
        nodes.append(amplicon_id)
        for next_amplicon in amplicons:
            if not has_qualifying_overlap(current_amplicon, next_amplicon, min_overlap):
                continue
            # --> write to graph
            if amplicon_id not in amplicon_graph:
                amplicon_graph[amplicon_id] = {
                    next_amplicon["id"]: (
                        next_amplicon.get("off_targets", False),
                        next_amplicon["penalty"]
                    )
                }
            else:
                amplicon_graph[amplicon_id][next_amplicon["id"]] = (
                    next_amplicon.get("off_targets", False),
                    next_amplicon["penalty"]
                )

    # return a graph object
    return Graph(nodes, amplicon_graph)


def dijkstra_algorithm(graph, start_node):
    # MASKED: Implementation of Dijkstra's algorithm to find shortest paths between nodes in a weighted graph for optimal amplicon scheme design implementation
    raise NotImplementedError("This function is masked for testing purposes.")


def get_end_node(previous_nodes, shortest_path, amplicons):
    """
    get the target node with the lowest penalty costs out of all
    nodes that have the same maximum end position
    """
    stop_nucleotide, possible_end_nodes = 0, {}

    for node in previous_nodes.keys():
        # check if a node has a larger stop -> empty dict and set new
        # best stop nucleotide
        amplicon_stop = amplicons[node]["RIGHT"][2]
        if amplicon_stop > stop_nucleotide:
            possible_end_nodes = {node: shortest_path[node]}
            stop_nucleotide = amplicon_stop
        # if nodes have the same stop nucleotide, add to dictionary
        elif amplicon_stop == stop_nucleotide:
            possible_end_nodes[node] = shortest_path[node]

    # return the end node with the lowest penalty costs
    return min(possible_end_nodes.items(), key=lambda x: x[1])


def get_min_path(previous_nodes, start_node, target_node):
    """
    get the min path from the start to stop node from the
    previosuly calculated shortest path
    """
    path = []
    node = target_node

    while node != start_node:
        path.append(node)
        node = previous_nodes[node]
    # Add the start node manually
    path.append(start_node)

    # return the inverse list
    return path[::-1]


def create_scheme(amplicon_path, amplicons_by_id):
    """
    creates the final tiled-amplicon scheme
    """
    amplicon_scheme = []

    for pool in (0, 1):
        for amp_id in amplicon_path[pool::2]:
            amplicons_by_id[amp_id]["pool"] = pool
            amplicon_scheme.append(amplicons_by_id[amp_id])

    return amplicon_scheme


def find_best_covering_scheme(amplicons, amplicon_graph):
    """
    this brute forces the amplicon scheme search until the largest
    coverage with the minimal costs is achieved.
    """
    # ini
    best_coverage = 0
    max_stop = max(amplicons, key=lambda x: x["RIGHT"][2])["RIGHT"][2]
    lowest_costs = (float('infinity'),)
    # a dict for fast access to amplicons by their ID
    amps_by_id = {amp["id"]: amp for amp in amplicons}
    for amplicon in amplicons:
        # if the currently best coverage + start nucleotide of the currently tested amplicon
        # is smaller than the maximal stop nucleotide there might be a better amplicon
        # scheme that covers more of the genome
        if amplicon["LEFT"][1] + best_coverage <= max_stop:
            previous_nodes, shortest_path = dijkstra_algorithm(amplicon_graph, amplicon["id"])
            # only continue if there are previous_nodes
            if previous_nodes:
                target_node, costs = get_end_node(previous_nodes, shortest_path, amps_by_id)
                coverage = amps_by_id[target_node]["RIGHT"][2] - amplicon["LEFT"][1]
                # if the new coverage is larger, go for the larger coverage
                if coverage > best_coverage:
                    best_start_node = amplicon["id"]
                    best_target_node = target_node
                    best_previous_nodes = previous_nodes
                    lowest_costs = costs
                    best_coverage = coverage
                # if the coverages are identical, go for the lowest costs
                elif coverage == best_coverage:
                    if costs < lowest_costs:
                        best_start_node = amplicon["id"]
                        best_target_node = target_node
                        best_previous_nodes = previous_nodes
                        lowest_costs = costs
                        best_coverage = coverage
            else:
                # check if the single amplicon has the largest coverage so far
                coverage = amplicon["length"]
                if coverage > best_coverage:
                    best_start_node = amplicon["id"]


Complete the function implementation replacing "raise NotImplementedError".