def add_room(model, solution=None, linear=False, delta=<NUM_LIT>, epsilon=<NUM_LIT>):
if '<STR_LIT>' in model.solver.variables:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if solution is None:<EOL><INDENT>solution = pfba(model)<EOL><DEDENT>prob = model.problem<EOL>variable = prob.Variable("<STR_LIT>", ub=solution.objective_value)<EOL>constraint = prob.Constraint(<EOL>model.solver.objective.expression - variable,<EOL>ub=<NUM_LIT:0.0>,<EOL>lb=<NUM_LIT:0.0>,<EOL>name="<STR_LIT>"<EOL>)<EOL>model.objective = prob.Objective(Zero, direction="<STR_LIT>", sloppy=True)<EOL>vars_and_cons = [variable, constraint]<EOL>obj_vars = []<EOL>for rxn in model.reactions:<EOL><INDENT>flux = solution.fluxes[rxn.id]<EOL>if linear:<EOL><INDENT>y = prob.Variable("<STR_LIT>" + rxn.id, lb=<NUM_LIT:0>, ub=<NUM_LIT:1>)<EOL>delta = epsilon = <NUM_LIT:0.0><EOL><DEDENT>else:<EOL><INDENT>y = prob.Variable("<STR_LIT>" + rxn.id, type="<STR_LIT>")<EOL><DEDENT>w_u = flux + (delta * abs(flux)) + epsilon<EOL>upper_const = prob.Constraint(<EOL>rxn.flux_expression - y * (rxn.upper_bound - w_u),<EOL>ub=w_u, name="<STR_LIT>" + rxn.id)<EOL>w_l = flux - (delta * abs(flux)) - epsilon<EOL>lower_const = prob.Constraint(<EOL>rxn.flux_expression - y * (rxn.lower_bound - w_l),<EOL>lb=w_l, name="<STR_LIT>" + rxn.id)<EOL>vars_and_cons.extend([y, upper_const, lower_const])<EOL>obj_vars.append(y)<EOL><DEDENT>model.add_cons_vars(vars_and_cons)<EOL>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in obj_vars})<EOL>
r"""
    Add constraints and objective for ROOM.

    This function adds variables and constraints for applying regulatory
    on/off minimization (ROOM) to the model.

    Parameters
    ----------
    model : cobra.Model
        The model to add ROOM constraints and objective to.
    solution : cobra.Solution, optional
        A previous solution to use as a reference. If no solution is given,
        one will be computed using pFBA.
    linear : bool, optional
        Whether to use the linear ROOM formulation or not (default False).
    delta: float, optional
        The relative tolerance range which is additive in nature
        (default 0.03).
    epsilon: float, optional
        The absolute range of tolerance which is multiplicative
        (default 0.001).

    Notes
    -----
    The formulation used here is the same as stated in the original paper [1]_.
    The mathematical expression is given below:

    minimize \sum_{i=1}^m y^i
    s.t. Sv = 0
         v_min <= v <= v_max
         v_j = 0
         j ∈ A
         for 1 <= i <= m
         v_i - y_i(v_{max,i} - w_i^u) <= w_i^u      (1)
         v_i - y_i(v_{min,i} - w_i^l) <= w_i^l      (2)
         y_i ∈ {0,1}                                (3)
         w_i^u = w_i + \delta|w_i| + \epsilon
         w_i^l = w_i - \delta|w_i| - \epsilon

    So, for the linear version of the ROOM , constraint (3) is relaxed to
    0 <= y_i <= 1.

    See Also
    --------
    pfba : parsimonious FBA

    References
    ----------
    .. [1] Tomer Shlomi, Omer Berkman and Eytan Ruppin, "Regulatory on/off
     minimization of metabolic flux changes after genetic perturbations",
     PNAS 2005 102 (21) 7695-7700; doi:10.1073/pnas.0406346102