def generate_bqm(graph, table, decision,
                 linear_energy_ranges=None, quadratic_energy_ranges=None, min_classical_gap=2,
                 precision=7, max_decision=8, max_variables=10,
                 return_auxiliary=False):
    """Get a binary quadratic model with specific ground states.

    Args:
        graph (:obj:`~networkx.Graph`):
            Defines the structure of the generated binary quadratic model.

        table (iterable):
            Iterable of valid configurations (of spin-values). Each configuration is a tuple of
            variable assignments ordered by `decision`.

        decision (list/tuple):
            The variables in the binary quadratic model which have specified configurations.

        linear_energy_ranges (dict, optional):
            Dict of the form {v: (min, max, ...} where min and max are the range of values allowed
            to v. The default range is [-2, 2].

        quadratic_energy_ranges (dict, optional):
            Dict of the form {(u, v): (min, max), ...} where min and max are the range of values
            allowed to (u, v). The default range is [-1, 1].

        min_classical_gap (float):
            The minimum energy gap between the highest feasible state and the lowest infeasible
            state.

        precision (int, optional, default=7):
            Values returned by the optimization solver are rounded to `precision` digits of
            precision.

        max_decision (int, optional, default=4):
            Maximum number of decision variables allowed. The algorithm is valid for arbitrary
            sizes of problem but can be extremely slow.

        max_variables (int, optional, default=4):
            Maximum number of variables allowed. The algorithm is valid for arbitrary
            sizes of problem but can be extremely slow.

        return_auxiliary (bool, optional, False):
            If True, the auxiliary configurations are returned for each configuration in table.

    Returns:
        If return_auxiliary is False:

            :obj:`dimod.BinaryQuadraticModel`: The binary quadratic model.

            float: The classical gap.

        If return_auxiliary is True:

            :obj:`dimod.BinaryQuadraticModel`: The binary quadratic model.

            float: The classical gap.

            dict: The auxiliary configurations, keyed on the configurations in table.

    Raises:
        ImpossiblePenaltyModel: If the penalty model cannot be built. Normally due
            to a non-zero infeasible gap.

    """

    # Developer note: This function is input checking and output formatting. The logic is
    # in _generate_ising

    if not isinstance(graph, nx.Graph):
        raise TypeError("expected input graph to be a NetworkX Graph.")

    if not set().union(*table).issubset({-1, 1}):
        raise ValueError("expected table to be spin-valued")

    if not isinstance(decision, list):
        decision = list(decision)  # handle iterables
    if not all(v in graph for v in decision):
        raise ValueError("given graph does not match the variable labels in decision variables")

    num_var = len(decision)
    if any(len(config) != num_var for config in table):
        raise ValueError("number of decision variables does not match all of the entires in the table")

    if len(decision) > max_decision:
        raise ValueError(("The table is too large. Note that larger models can be built by setting "
                          "max_decision to a higher number, but generation could be extremely slow."))

    if len(graph) > max_variables:
        raise ValueError(("The graph is too large. Note that larger models can be built by setting "
                          "max_variables to a higher number, but generation could be extremely slow."))

    if linear_energy_ranges is None:
        linear_energy_ranges = defaultdict(lambda: (-2, 2))
    if quadratic_energy_ranges is None:
        quadratic_energy_ranges = defaultdict(lambda: (-1, 1))

    if not isinstance(table, Mapping):
        table = {config: 0. for config in table}

    h, J, offset, gap, aux = _generate_ising(graph, table, decision, min_classical_gap,
                                             linear_energy_ranges, quadratic_energy_ranges)

    bqm = dimod.BinaryQuadraticModel.empty(dimod.SPIN)
    bqm.add_variables_from((v, round(bias, precision)) for v, bias in h.items())
    bqm.add_interactions_from((u, v, round(bias, precision)) for (u, v), bias in J.items())
    bqm.add_offset(round(offset, precision))

    if return_auxiliary:
        return bqm, round(gap, precision), aux
    else:
        return bqm, round(gap, precision)
Get a binary quadratic model with specific ground states.

    Args:
        graph (:obj:`~networkx.Graph`):
            Defines the structure of the generated binary quadratic model.

        table (iterable):
            Iterable of valid configurations (of spin-values). Each configuration is a tuple of
            variable assignments ordered by `decision`.

        decision (list/tuple):
            The variables in the binary quadratic model which have specified configurations.

        linear_energy_ranges (dict, optional):
            Dict of the form {v: (min, max, ...} where min and max are the range of values allowed
            to v. The default range is [-2, 2].

        quadratic_energy_ranges (dict, optional):
            Dict of the form {(u, v): (min, max), ...} where min and max are the range of values
            allowed to (u, v). The default range is [-1, 1].

        min_classical_gap (float):
            The minimum energy gap between the highest feasible state and the lowest infeasible
            state.

        precision (int, optional, default=7):
            Values returned by the optimization solver are rounded to `precision` digits of
            precision.

        max_decision (int, optional, default=4):
            Maximum number of decision variables allowed. The algorithm is valid for arbitrary
            sizes of problem but can be extremely slow.

        max_variables (int, optional, default=4):
            Maximum number of variables allowed. The algorithm is valid for arbitrary
            sizes of problem but can be extremely slow.

        return_auxiliary (bool, optional, False):
            If True, the auxiliary configurations are returned for each configuration in table.

    Returns:
        If return_auxiliary is False:

            :obj:`dimod.BinaryQuadraticModel`: The binary quadratic model.

            float: The classical gap.

        If return_auxiliary is True:

            :obj:`dimod.BinaryQuadraticModel`: The binary quadratic model.

            float: The classical gap.

            dict: The auxiliary configurations, keyed on the configurations in table.

    Raises:
        ImpossiblePenaltyModel: If the penalty model cannot be built. Normally due
            to a non-zero infeasible gap.