<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def min_vertex_coloring(G, sampler=None, **sampler_args):
 """Returns an approximate minimum vertex coloring. Vertex coloring is the problem of assigning a color to the vertices of a graph in a way that no adjacent vertices have the same color. A minimum vertex coloring is the problem of solving the vertex coloring problem using the smallest number of colors. Since neighboring vertices must satisfy a constraint of having different colors, the problem can be posed as a binary constraint satisfaction problem. Defines a QUBO with ground states corresponding to minimum vertex colorings and uses the sampler to sample from it. Parameters G : NetworkX graph The graph on which to find a minimum vertex coloring. sampler A binary quadratic model sampler. A sampler is a process that samples from low energy states in models defined by an Ising equation or a Quadratic Unconstrained Binary Optimization Problem (QUBO). A sampler is expected to have a 'sample_qubo' and 'sample_ising' method. A sampler is expected to return an iterable of samples, in order of increasing energy. If no sampler is provided, one must be provided using the `set_default_sampler` function. sampler_args Additional keyword parameters are passed to the sampler. Returns ------- coloring : dict A coloring for each vertex in G such that no adjacent nodes Example ------- This example colors a single Chimera unit cell. It colors the four horizontal qubits one color (0) and the four vertical qubits another (1). {0: 0, 1: 0, 2: 0, 3: 0, 4: 1, 5: 1, 6: 1, 7: 1} References .. [DWMP] Dahl, E., "Programming the D-Wave: Map Coloring Problem", https://www.dwavesys.com/sites/default/files/Map%20Coloring%20WP2.pdf Notes ----- Samplers by their nature may not return the optimal solution. This function does not attempt to confirm the quality of the returned sample. """


    # if the given graph is not connected, apply the function to each connected component
    # seperately.
    if not nx.is_connected(G):
        coloring = {}
        for subG in (G.subgraph(c).copy() for c in nx.connected_components(G)):
            sub_coloring = min_vertex_coloring(subG, sampler, **sampler_args)
            coloring.update(sub_coloring)
        return coloring

    n_nodes = len(G)  # number of nodes
    n_edges = len(G.edges)  # number of edges

    # ok, first up, we can eliminate a few graph types trivially

    # Graphs with no edges, have chromatic number 1
    if not n_edges:
        return {node: 0 for node in G}

    # Complete graphs have chromatic number N
    if n_edges == n_nodes * (n_nodes - 1) // 2:
        return {node: color for color, node in enumerate(G)}

    # The number of variables in the QUBO is approximately the number of nodes in the graph
    # times the number of potential colors, so we want as tight an upper bound on the
    # chromatic number (chi) as possible
    chi_ub = _chromatic_number_upper_bound(G, n_nodes, n_edges)

    # now we can start coloring. Without loss of generality, we can determine some of
    # the node colors before trying to solve.
    partial_coloring, possible_colors, chi_lb = _partial_precolor(G, chi_ub)

    # ok, to get the rest of the coloring, we need to start building the QUBO. We do this
    # by assigning a variable x_v_c for each node v and color c. This variable will be 1
    # when node v is colored c, and 0 otherwise.

    # let's assign an index to each of the variables
    counter = itertools.count()
    x_vars = {v: {c: next(counter) for c in possible_colors[v]} for v in possible_colors}

    # now we have three different constraints we wish to add.

    # the first constraint enforces the coloring rule, that for each pair of vertices
    # u, v that share an edge, they should be different colors
    Q_neighbor = _vertex_different_colors_qubo(G, x_vars)

    # the second constraint enforces that each vertex has a single color assigned
    Q_vertex = _vertex_one_color_qubo(x_vars)

    # the third constraint is that we want a minimum vertex coloring, so we want to
    # disincentivize the colors we might not need.
    Q_min_color = _minimum_coloring_qubo(x_vars, chi_lb, chi_ub, magnitude=.75)

    # combine all three constraints
    Q = Q_neighbor
    for (u, v), bias in iteritems(Q_vertex):
        if (u, v) in Q:
            Q[(u, v)] += bias
        elif (v, u) in Q:
            Q[(v, u)] += bias
        else:
            Q[(u, v)] = bias
    for (v, v), bias in iteritems(Q_min_color):
        if (v, v) in Q:
            Q[(v, v)] += bias
        else:
            Q[(v, v)] = bias

    # use the sampler to find low energy states
    response = sampler.sample_qubo(Q, **sampler_args)

    # we want the lowest energy sample
    sample = next(iter(response))

    # read off the coloring
    for v in x_vars:
        for c in x_vars[v]:
            if sample[x_vars[v][c]]:
                partial_coloring[v] = c

    return partial_coloring