def random_2in4sat(num_variables, num_clauses, vartype=dimod.BINARY, satisfiable=True):
if num_variables < <NUM_LIT:4>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if num_clauses > <NUM_LIT:16> * _nchoosek(num_variables, <NUM_LIT:4>):  <EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>csp = ConstraintSatisfactionProblem(vartype)<EOL>variables = list(range(num_variables))<EOL>constraints = set()<EOL>if satisfiable:<EOL><INDENT>values = tuple(vartype.value)<EOL>planted_solution = {v: choice(values) for v in variables}<EOL>configurations = [(<NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>), (<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:1>), (<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>, <NUM_LIT:1>),<EOL>(<NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>), (<NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:1>, <NUM_LIT:0>), (<NUM_LIT:1>, <NUM_LIT:1>, <NUM_LIT:0>, <NUM_LIT:0>)]<EOL>while len(constraints) < num_clauses:<EOL><INDENT>constraint_variables = sorted(sample(variables, <NUM_LIT:4>))<EOL>config = choice(configurations)<EOL>pos = tuple(v for idx, v in enumerate(constraint_variables) if config[idx] == (planted_solution[v] > <NUM_LIT:0>))<EOL>neg = tuple(v for idx, v in enumerate(constraint_variables) if config[idx] != (planted_solution[v] > <NUM_LIT:0>))<EOL>const = sat2in4(pos=pos, neg=neg, vartype=vartype)<EOL>assert const.check(planted_solution)<EOL>constraints.add(const)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>while len(constraints) < num_clauses:<EOL><INDENT>constraint_variables = sorted(sample(variables, <NUM_LIT:4>))<EOL>pos = tuple(v for v in constraint_variables if random() > <NUM_LIT>)<EOL>neg = tuple(v for v in constraint_variables if v not in pos)<EOL>const = sat2in4(pos=pos, neg=neg, vartype=vartype)<EOL>constraints.add(const)<EOL><DEDENT><DEDENT>for const in constraints:<EOL><INDENT>csp.add_constraint(const)<EOL><DEDENT>for v in variables:<EOL><INDENT>csp.add_variable(v)<EOL><DEDENT>return csp<EOL>
Random two-in-four (2-in-4) constraint satisfaction problem.

    Args:
        num_variables (integer): Number of variables (at least four).
        num_clauses (integer): Number of constraints that together constitute the
            constraint satisfaction problem.
        vartype (Vartype, optional, default='BINARY'): Variable type. Accepted
            input values:

            * Vartype.SPIN, 'SPIN', {-1, 1}
            * Vartype.BINARY, 'BINARY', {0, 1}
        satisfiable (bool, optional, default=True): True if the CSP can be satisfied.

    Returns:
        CSP (:obj:`.ConstraintSatisfactionProblem`): CSP that is satisfied when its variables
        are assigned values that satisfy a two-in-four satisfiability problem.

    Examples:
        This example creates a CSP with 6 variables and two random constraints and checks
        whether a particular assignment of variables satisifies it.

        >>> import dwavebinarycsp
        >>> import dwavebinarycsp.factories as sat
        >>> csp = sat.random_2in4sat(6, 2)
        >>> csp.constraints    # doctest: +SKIP
        [Constraint.from_configurations(frozenset({(1, 0, 1, 0), (1, 0, 0, 1), (1, 1, 1, 1), (0, 1, 1, 0), (0, 0, 0, 0),
         (0, 1, 0, 1)}), (2, 4, 0, 1), Vartype.BINARY, name='2-in-4'),
         Constraint.from_configurations(frozenset({(1, 0, 1, 1), (1, 1, 0, 1), (1, 1, 1, 0), (0, 0, 0, 1),
         (0, 1, 0, 0), (0, 0, 1, 0)}), (1, 2, 4, 5), Vartype.BINARY, name='2-in-4')]
        >>> csp.check({0: 1, 1: 0, 2: 1, 3: 1, 4: 0, 5: 0})       # doctest: +SKIP
        True