def createdirectedgraph(szM, M, M_assignment):
    """Create a directed graph:
    The data structure of the result is a dicitionary within a dictionary
    such as
    weightedGraph = {0 : {1:259.55, 15:48.19, 16:351.95},
    1 : {2:249.354, 16:351.951, 17:108.97},
    2 : {3:553.30, 17:108.97, 18:341.78}, ...}

    It defines the possible nodes to reach from a particular node, and the weight that
    is associated with the path to each of the possible nodes.

    :param: szM: list, shape of matrix M
    :param: M: array-like, matrix of vector length differences
    :param: M_assignment: array-like, Matrix, arranged with values from 0 to number of entries in M

    :return: weighted graph: dict, Dictionary within a dictionary pairing weights (distances) with
            node-pairings

    """
    adjacent = {}
    weight = {}
    for i in range(0, szM[0]):
        for j in range(0, szM[1]):
            currentNode = i * szM[1] + j
            if (i == szM[0] - 1) & (j < szM[1] - 1):
                adjacent[M_assignment[i, j]] = [currentNode + 1]
                weight[M_assignment[i, j]] = [M[i, j + 1]]
            elif (i < szM[0] - 1) & (j == szM[1] - 1):
                adjacent[M_assignment[i, j]] = [currentNode + szM[1]]
                weight[M_assignment[i, j]] = [M[i + 1, j]]
            elif (i == szM[0] - 1) & (j == szM[1] - 1):
                adjacent[M_assignment[i, j]] = [currentNode]
                weight[M_assignment[i, j]] = [0]
            else:
                adjacent[M_assignment[i, j]] = [currentNode + 1, 
                    currentNode + szM[1], currentNode + szM[1] + 1]
                weight[M_assignment[i, j]] = [M[i, j + 1], M[i + 1, j], M[i +
                    1, j + 1]]
    Startnodes = range(0, szM[0] * szM[1])
    weightedEdges = []
    for i in range(0, len(adjacent)):
        weightedEdges.append(list(zip(list(adjacent.values())[i], list(
            weight.values())[i])))
    weightedGraph = {}
    for i in range(0, len(weightedEdges)):
        weightedGraph[Startnodes[i]] = dict(weightedEdges[i])
    return weightedGraph
