import math


def DL_Nodes(V, W, q):
    """function to compute the shannon-optimal code to describe the vertices in a graph pattern

    Args:
        V (int): number of nodes in a supergraph of original dataset
        W (int): number of nodes in a graph pattern
        q (float): expected size of a pattern, i.e., ratio of original dataset size, in range 0.0 to 1.0

    Returns:
        float: shannon-optimal code to describe W vertices
    """
    incCost = math.log((1.0 - q) / q)
    excCost = V * math.log(1.0 / (1.0 - q))
    dl = excCost
    if isinstance(W, int) or isinstance(W, float):
        dl = W * incCost + excCost
    elif isinstance(W, list):
        dl = len(W) * incCost + excCost
    else:
        raise Exception('Input parameter W is invalid')
    return dl