Esempio n. 1
0
    def testGmp(self):
        """Test reading/writing GNU MathProg format."""
        # there is no write keyword for 'gmp'; write the file manually
        self.f.write('''
        var x, >= 0, <= 1;
        var y, >= 0, <= 1;
        maximize
        value: x + y;
        subject to
        row: .5*x + y <= 1;
        end;
        '''.encode('utf-8'))
        self.f.flush()
        lp = LPX(gmp=self.f.name)
        # TODO: why is this two?
        self.assertEqual(len(lp.rows), 2)
        self.assertEqual(len(lp.cols), 2)
        self.assertEqual(lp.cols[0].name, 'x')
        self.assertEqual(lp.cols[1].name, 'y')

        # try to read a non-existing file
        with self.assertRaises(RuntimeError) as cm:
            lp = LPX(gmp='not a real file')
        self.assertIn('GMP model reader failed', str(cm.exception))

        # try to write to a non-existing path
        with self.assertRaises(ValueError) as cm:
            lp = LPX(gmp=())
        self.assertIn('model tuple must have 1<=length<=3', str(cm.exception))

        with self.assertRaises(TypeError) as cm:
            lp = LPX(gmp={})
        self.assertIn('model arg must be string or tuple', str(cm.exception))
Esempio n. 2
0
    def solve_sat(self, expression=None, callback=None,
                  return_processor=None, kwargs={}):
        """Runs a solve sat with a callback.  This is similar to the
        other SAT solving procedures in this test suite, with some
        modifications to enable testing of the MIP callback
        functionality.

        expression is the expression argument, and defaults to the
        expression declared in the MIPCallbackTest.

        callback is the callback instance being tested.

        return_processor is a function called with the retval from the
        lp.integer call, and the lp, e.g., return_processor(retval,
        lp), prior to any further processing of the results.

        kwargs is a dictionary of other optional keyword arguments and
        their values which is passed to the lp.integer solution
        procedure."""
        if expression is None:
            expression = self.expression
        if len(expression) == 0:
            return []
        numvars = max(max(abs(v) for v in clause) for clause in expression)
        lp = LPX()
        lp.cols.add(2*numvars)
        for col in lp.cols:
            col.bounds = 0.0, 1.0

        def lit2col(lit):
            if lit > 0:
                return 2*lit-2
            return 2*(-lit)-1

        for i in range(1, numvars+1):
            lp.cols[lit2col(i)].name = 'x_%d' % i
            lp.cols[lit2col(-i)].name = '!x_%d' % i
            lp.rows.add(1)
            lp.rows[-1].matrix = [(lit2col(i), 1.0), (lit2col(-i), 1.0)]
            lp.rows[-1].bounds = 1.0
        for clause in expression:
            lp.rows.add(1)
            lp.rows[-1].matrix = [(lit2col(lit), 1.0) for lit in clause]
            lp.rows[-1].bounds = 1, None
        retval = lp.simplex()
        if retval is not None:
            return None
        if lp.status != 'opt':
            return None
        for col in lp.cols:
            col.kind = int
        retval = lp.integer(callback=callback, **kwargs)
        if return_processor:
            return_processor(retval, lp)
        if retval is not None:
            return None
        if lp.status != 'opt':
            return None
        return [col.value > 0.99 for col in lp.cols[::2]]
Esempio n. 3
0
 def testLpxSetMatrix(self):
     lp = LPX()
     with self.assertRaises(ValueError) as cm:
         lp.matrix = [(1, 2, 3, 4)]
     self.assertIn(
         'matrix entry tuple has length 4; 3 is required',
         str(cm.exception)
     )
Esempio n. 4
0
 def testLpxErase(self):
     lp = LPX()
     lp.cols.add(2)
     lp.rows.add(2)
     self.assertEqual(len(lp.cols), 2)
     self.assertEqual(len(lp.rows), 2)
     lp.erase()
     self.assertEqual(len(lp.cols), 0)
     self.assertEqual(len(lp.rows), 0)
Esempio n. 5
0
    def testLpxKkt(self):
        lp = LPX()

        with self.assertRaises(RuntimeError) as cm:
            lp.kkt()
        self.assertIn(
            'cannot get KKT when primal or dual basic solution undefined',
            str(cm.exception)
        )
def create_problem(cobra_model, **kwargs):
    """Solver-specific method for constructing a solver problem from
    a cobra.Model.  This can be tuned for performance using kwargs

    """
    metabolite_to_index = {r: i for i, r in enumerate(cobra_model.metabolites)}

    lp = LPX()  # Create empty problem instance
    lp.name = 'cobra'  # Assign symbolic name to problem
    lp.rows.add(len(cobra_model.metabolites))
    lp.cols.add(len(cobra_model.reactions))

    for r, the_metabolite in zip(lp.rows, cobra_model.metabolites):
        r.name = the_metabolite.id
        b = float(the_metabolite._bound)
        c = the_metabolite._constraint_sense
        if c == 'E':
            r.bounds = b, b  # Set metabolite to steady state levels
        elif c == 'L':
            r.bounds = None, b
        elif c == 'G':
            r.bounds = b, None
        else:
            raise ValueError("invalid constraint sense")

    objective_coefficients = []
    linear_constraints = []
    for c, the_reaction in zip(lp.cols, cobra_model.reactions):
        c.name = the_reaction.id
        c.kind = variable_kind_dict[the_reaction.variable_kind]
        c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
        objective_coefficients.append(float(
            the_reaction.objective_coefficient))
        for metabolite, coefficient in iteritems(the_reaction._metabolites):
            metabolite_index = metabolite_to_index[metabolite]
            linear_constraints.append((metabolite_index, c.index, coefficient))

    #Add the new objective coefficients to the problem
    lp.obj[:] = objective_coefficients
    #Need to assign lp.matrix after constructing the whole list
    #linear_constraints.sort()  # if we wanted to be 100% deterministic
    lp.matrix = linear_constraints

    # make sure the objective sense is set in create_problem
    objective_sense = kwargs.get("objective_sense", "maximize")
    set_parameter(lp, "objective_sense", objective_sense)

    return lp
Esempio n. 7
0
def create_problem(cobra_model, **kwargs):
    """Solver-specific method for constructing a solver problem from
    a cobra.Model.  This can be tuned for performance using kwargs

    """
    metabolite_to_index = {r: i for i, r in enumerate(cobra_model.metabolites)}

    lp = LPX()        # Create empty problem instance
    lp.name = 'cobra'     # Assign symbolic name to problem
    lp.rows.add(len(cobra_model.metabolites))
    lp.cols.add(len(cobra_model.reactions))

    for r, the_metabolite in zip(lp.rows, cobra_model.metabolites):
        r.name = the_metabolite.id
        b = float(the_metabolite._bound)
        c = the_metabolite._constraint_sense
        if c == 'E':
            r.bounds = b, b     # Set metabolite to steady state levels
        elif c == 'L':
            r.bounds = None, b
        elif c == 'G':
            r.bounds = b, None
        else:
            raise ValueError("invalid constraint sense")

    objective_coefficients = []
    linear_constraints = []
    for c, the_reaction in zip(lp.cols, cobra_model.reactions):
        c.name = the_reaction.id
        c.kind = variable_kind_dict[the_reaction.variable_kind]
        c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
        objective_coefficients.append(float(the_reaction.objective_coefficient))
        for metabolite, coefficient in iteritems(the_reaction._metabolites):
            metabolite_index = metabolite_to_index[metabolite]
            linear_constraints.append((metabolite_index, c.index, coefficient))

    #Add the new objective coefficients to the problem
    lp.obj[:] = objective_coefficients
    #Need to assign lp.matrix after constructing the whole list
    #linear_constraints.sort()  # if we wanted to be 100% deterministic
    lp.matrix = linear_constraints

    # make sure the objective sense is set in create_problem
    objective_sense = kwargs.get("objective_sense", "maximize")
    set_parameter(lp, "objective_sense", objective_sense)

    return lp
Esempio n. 8
0
 def testObjectiveAssignment(self):
     lp = LPX()
     with self.assertRaises(TypeError) as cm:
         del(lp.obj[0])
     self.assertIn(
         "objective function doesn't support item deletion",
         str(cm.exception)
     )
Esempio n. 9
0
    def testLpxRay(self):
        lp = LPX()
        self.assertTrue(lp.ray is None)
        lp.cols.add(2)
        x1, x2 = lp.cols[0:2]
        lp.obj[:] = [-1.0, 1.0]
        lp.rows.add(2)
        r1, r2 = lp.rows[0:2]
        r1.matrix = [1.0, -1.0]
        r1.bounds = (-3, None)
        r2.matrix = [-1.0, 2.0]
        r2.bounds = (-2.0, None)
        x1.bounds = None
        x2.bounds = None
        lp.simplex()

        self.assertEqual(lp.status, 'unbnd')
        self.assertTrue(lp.ray.iscol)
Esempio n. 10
0
    def test_transform_row_with_variable_from_other_lp(self):
        other_lp = LPX()
        other_lp.cols.add(3)

        with self.assertRaises(ValueError) as context:
            self.lp.transform_row([(other_lp.cols[0], 3.0)])

        self.assertIn("variable not associated with this LPX",
                      str(context.exception))
Esempio n. 11
0
    def solve_sat(self, expression):
        """Attempts to satisfy a formula of conjunction of disjunctions.

        If there are n variables in the expression, this will return a
        list of length n, all elements booleans.  The truth of element i-1
        corresponds to the truth of variable i.

        If no satisfying assignment could be found, None is returned."""
        if len(expression) == 0:
            return []
        numvars = max(max(abs(v) for v in clause) for clause in expression)
        lp = LPX()
        lp.cols.add(2*numvars)
        for col in lp.cols:
            col.bounds = 0.0, 1.0

        def lit2col(lit):
            if lit > 0:
                return 2*lit-2
            return 2*(-lit)-1

        for i in range(1, numvars+1):
            lp.cols[lit2col(i)].name = 'x_%d' % i
            lp.cols[lit2col(-i)].name = '!x_%d' % i
            lp.rows.add(1)
            lp.rows[-1].matrix = [(lit2col(i), 1.0), (lit2col(-i), 1.0)]
            lp.rows[-1].bounds = 1.0
        for clause in expression:
            lp.rows.add(1)
            lp.rows[-1].matrix = [(lit2col(lit), 1.0) for lit in clause]
            lp.rows[-1].bounds = 1, None
        retval = lp.simplex()
        if retval is not None:
            return None
        if lp.status != 'opt':
            return None
        for col in lp.cols:
            col.kind = int
        retval = lp.integer()
        if retval is not None:
            return None
        if lp.status != 'opt':
            return None
        return [col.value > 0.99 for col in lp.cols[::2]]
Esempio n. 12
0
def create_problem(cobra_model, objective_sense="maximize", lp=None):
    if lp is None:
        lp = LPX()  # Create empty problem instance
        lp.name = cobra_model.id
        lp.rows.add(len(cobra_model.metabolites))
        lp.cols.add(len(cobra_model.reactions))

    if objective_sense == 'maximize':
        lp.obj.maximize = True
    elif objective_sense == 'minimize':
        lp.obj.maximize = False
    else:
        raise ValueError("objective_sense not 'maximize' or 'minimize'")

    # create metabolites/constraints as rows
    for i, r in enumerate(lp.rows):
        metabolite = cobra_model.metabolites[i]
        r.name = metabolite.id
        b = float(metabolite._bound)
        c = metabolite._constraint_sense
        # constraint sense is set by changing the bounds
        if c == 'E':
            r.bounds = (b, b)
        elif c == 'L':
            r.bounds = (None, b)
        elif c == 'G':
            r.bounds = (b, None)
        else:
            raise ValueError("%s is not a valid constraint_sense" % c)

    # create reactions/variables as columns
    for i, c in enumerate(lp.cols):
        reaction = cobra_model.reactions[i]
        c.name = reaction.id
        c.kind = variable_kind_dict[reaction.variable_kind]
        c.bounds = (reaction.lower_bound, reaction.upper_bound)
        lp.obj[i] = float(reaction.objective_coefficient)

    # create S matrix
    lp.matrix = [(int(i), int(j), c) \
        for (i, j), c in cobra_model.to_array_based_model().S.todok().iteritems()]
    return lp
Esempio n. 13
0
 def setUp(self):
     lp = self.lp = LPX()
     lp.rows.add(1)
     lp.cols.add(2)
     for c in lp.cols:
         c.bounds = 0, 1
     lp.obj[:] = [1, 1]
     lp.obj.maximize = True
     lp.rows[0].matrix = [0.5, 1.0]
     lp.rows[0].bounds = None, 1
     self.num_illegals = 100
Esempio n. 14
0
    def testFreeMps(self):
        """Test reading/writing free MPS format."""
        self.lp.write(freemps=self.f.name)
        lp = LPX(freemps=self.f.name)
        self.assertEqual(len(lp.rows), 1)
        self.assertEqual(len(lp.cols), 2)
        self.assertEqual(lp.cols[0].name, 'x')
        self.assertEqual(lp.cols[1].name, 'y')

        # try to read a non-existing file
        with self.assertRaises(RuntimeError) as cm:
            lp = LPX(freemps='not a real file')
        self.assertIn('Free MPS reader failed', str(cm.exception))

        # try to write to a non-existing path
        with self.assertRaises(RuntimeError) as cm:
            lp.write(freemps='not/a/real/file')
        self.assertIn(
            "writer for 'freemps' failed to write to 'not/a/real/file'",
            str(cm.exception)
        )
Esempio n. 15
0
 def setUp(self):
     lp = self.lp = LPX()
     lp.rows.add(1)
     lp.cols.add(2)
     lp.cols[0].name = 'x'
     lp.cols[1].name = 'y'
     for c in lp.cols:
         c.bounds = 0, 1
     lp.obj[:] = [1, 1]
     lp.obj.maximize = True
     lp.rows[0].matrix = [0.5, 1.0]
     lp.rows[0].bounds = None, 1
Esempio n. 16
0
    def testCpxLp(self):
        """Test reading/writing CPLEX LP format."""
        self.lp.write(cpxlp=self.f.name)
        lp = LPX(cpxlp=self.f.name)
        self.assertEqual(len(lp.rows), 1)
        self.assertEqual(len(lp.cols), 2)
        self.assertEqual(lp.cols[0].name, 'x')
        self.assertEqual(lp.cols[1].name, 'y')

        # try to read a non-existing file
        with self.assertRaises(RuntimeError) as cm:
            lp = LPX(cpxlp='not a real file')
        self.assertIn('CPLEX LP reader failed', str(cm.exception))

        # try to write to a non-existing path
        with self.assertRaises(RuntimeError) as cm:
            lp.write(cpxlp='not/a/real/file')
        self.assertIn(
            "writer for 'cpxlp' failed to write to 'not/a/real/file'",
            str(cm.exception)
        )
Esempio n. 17
0
 def setUp(self):
     lp = self.lp = LPX()
     lp.rows.add(2)
     lp.cols.add(2)
     for c in lp.cols:
         c.bounds = None, None
         c.kind = int
     lp.obj[:] = [1, 1]
     lp.obj.maximize = True
     lp.rows[0].matrix, lp.rows[1].matrix = [2, 1], [1, 2]
     lp.rows[0].bounds, lp.rows[1].bounds = (None, 6.5), (None, 6.5)
     lp.simplex()  # This should have both column vars at 2.1666...
     self.num_illegals = 100
Esempio n. 18
0
 def setUp(self):
     # create a new temp file for reading/writing to
     self.f = tempfile.NamedTemporaryFile()
     lp = self.lp = LPX()
     lp.rows.add(1)
     lp.cols.add(2)
     lp.cols[0].name = 'x'
     lp.cols[1].name = 'y'
     for c in lp.cols:
         c.bounds = 0, 1
     lp.obj[:] = [1, 1]
     lp.obj.maximize = True
     lp.rows[0].matrix = [0.5, 1.0]
     lp.rows[0].bounds = None, 1
Esempio n. 19
0
 def setUp(self):
     lp = self.lp = LPX()
     lp.rows.add(1)
     self.z = lp.rows[0]
     lp.cols.add(2)
     self.x = lp.cols[0]
     self.y = lp.cols[1]
     for c in lp.cols:
         c.bounds = 0, 1
     lp.obj[:] = [1, 1]
     lp.obj.maximize = True
     lp.rows[0].matrix = [0.5, 1.0]
     lp.rows[0].bounds = None, 1
     self.lp.simplex()
Esempio n. 20
0
    def testInit(self):
        with self.assertRaises(TypeError) as cm:
            LPX(gmp='', mps='')
        self.assertIn(
            'cannot specify multiple data sources',
            str(cm.exception)
        )

        with self.assertRaises(RuntimeError) as cm:
            LPX(gmp=('', None, ''))
        self.assertIn(
            'GMP model reader failed',
            str(cm.exception)
        )

        model = tempfile.NamedTemporaryFile(mode='w')
        model.write(MODEL)
        model.flush()

        data = tempfile.NamedTemporaryFile(mode='w')
        data.write(DATA)
        data.flush()

        with self.assertRaises(RuntimeError) as cm:
            LPX(gmp=(model.name, ''))
        self.assertIn(
            'GMP data reader failed',
            str(cm.exception)
        )

        with self.assertRaises(RuntimeError) as cm:
            LPX(gmp=(model.name, data.name))
        self.assertIn(
            'GMP generator failed',
            str(cm.exception)
        )
Esempio n. 21
0
    def testLpxInteger(self):
        lp = LPX()

        with self.assertRaises(RuntimeError) as cm:
            lp.integer()
        self.assertIn(
            'integer solver without presolve requires existing optimal basic '
            'solution',
            str(cm.exception)
        )

        with self.assertRaises(ValueError) as cm:
            lp.integer(ps_tm_lim=-1, presolve=True)
        self.assertIn('ps_tm_lim must be nonnegative', str(cm.exception))

        with self.assertRaises(ValueError) as cm:
            lp.integer(mip_gap=-1, presolve=True)
        self.assertIn('mip_gap must be non-negative', str(cm.exception))
Esempio n. 22
0
    def testGlp(self):
        """Test reading/writing GNU LP format."""
        self.lp.write(glp=self.f.name)
        lp = LPX(glp=self.f.name)
        self.assertEqual(len(lp.rows), 1)
        self.assertEqual(len(lp.cols), 2)
        self.assertEqual(lp.cols[0].name, 'x')
        self.assertEqual(lp.cols[1].name, 'y')

        # try to read a non-existing file
        with self.assertRaises(RuntimeError) as cm:
            lp = LPX(glp='not a real file')
        self.assertIn('GLPK LP/MIP reader failed', str(cm.exception))

        # try to write to a non-existing path
        with self.assertRaises(RuntimeError) as cm:
            lp.write(glp='not/a/real/file')
        self.assertIn("writer for 'glp' failed to write to 'not/a/real/file'",
                      str(cm.exception))
Esempio n. 23
0
    def testFreeMps(self):
        """Test reading/writing free MPS format."""
        self.lp.write(freemps=self.f.name)
        lp = LPX(freemps=self.f.name)
        self.assertEqual(len(lp.rows), 1)
        self.assertEqual(len(lp.cols), 2)
        self.assertEqual(lp.cols[0].name, 'x')
        self.assertEqual(lp.cols[1].name, 'y')

        # try to read a non-existing file
        with self.assertRaises(RuntimeError) as cm:
            lp = LPX(freemps='not a real file')
        self.assertIn('Free MPS reader failed', str(cm.exception))

        # try to write to a non-existing path
        with self.assertRaises(RuntimeError) as cm:
            lp.write(freemps='not/a/real/file')
        self.assertIn(
            "writer for 'freemps' failed to write to 'not/a/real/file'",
            str(cm.exception))
Esempio n. 24
0
from glpk import LPX

# set up to maximize the objective function
lp = LPX()
lp.name = 'example'
lp.obj.maximize = True

# append 3 rows, named p, q, r
row_names = ["p", "q", "r"]
lp.rows.add(len(row_names))

for r in lp.rows:
    r.name = row_names[r.index]

lp.rows[0].bounds = None, 100.0
lp.rows[1].bounds = None, 600.0
lp.rows[2].bounds = None, 150.0

# append 3 cols, named x0, x1, x2
lp.cols.add(3)

for c in lp.cols:
    c.name = 'x%d' % c.index
    c.bounds = 0.0, None

# set the objective coefficients and
# non-zero entries of the constraint matrix
lp.obj[:] = [ 5.0, 3.0, 2.0 ]
lp.matrix = [ 1.0, 1.0, 3.0, 10.0, 4.0, 5.0, 1.0, 1.0, 3.0 ]

# report the objective function value and structural variables
Esempio n. 25
0
def _optimize_glpk(
        cobra_model,
        new_objective=None,
        objective_sense='maximize',
        min_norm=0,
        the_problem=None,
        tolerance_optimality=1e-6,
        tolerance_feasibility=1e-6,
        tolerance_integer=1e-9,
        error_reporting=None,
        print_solver_time=False,
        lp_method=1,
        quadratic_component=None,
        reuse_basis=True,
        #Not implemented
        tolerance_barrier=None,
        lp_parallel=None,
        copy_problem=None,
        relax_b=None,
        update_problem_reaction_bounds=True):
    """Uses the GLPK (www.gnu.org/software/glpk/) optimizer via pyglpk
    (http://www.tfinley.net/software/pyglpk/release.html) to perform an optimization
    on cobra_model for the objective_coefficients in cobra_model._objective_coefficients
    based on the objective sense.

    cobra_model: A cobra.Model object

    new_objective: Reaction, String, or Integer referring to a reaction in
    cobra_model.reactions to set as the objective.  Currently, only supports single
    objective coeffients.  Will expand to include mixed objectives.

    objective_sense: 'maximize' or 'minimize'

    min_norm: not implemented

    the_problem: None or a problem object for the specific solver that can be used to hot
    start the next solution.

    tolerance_optimality: Solver tolerance for optimality.

    tolerance_feasibility: Solver tolerance for feasibility.

    error_reporting: None or True to disable or enable printing errors encountered
    when trying to find the optimal solution.
    
    print_solver_time: False or True.  Indicates if the time to calculate the solution
    should be displayed.

    quadratic_component: None.  GLPK cannot solve quadratic programs at the moment.

    reuse_basis: Boolean.  If True and the_problem is a model object for the solver,
    attempt to hot start the solution.  Currently, only True is available for GLPK

    
    update_problem_reaction_bounds: Boolean.  Set to True if you're providing the_problem
    and you've modified reaction bounds on your cobra_model since creating the_problem.  Only
    necessary for CPLEX
    
    lp.simplex() with Salmonella model:
         cold start: 0.42 seconds
         hot start: 0.0013 seconds
    """

    from numpy import zeros, array, nan
    #TODO: Speed up problem creation
    if hasattr(quadratic_component, 'todok'):
        raise Exception('GLPK cannot solve quadratic programs please '+\
                        'try using the gurobi or cplex solvers')

    from glpk import LPX
    from cobra.flux_analysis.objective import update_objective
    from cobra.solvers.legacy import status_dict, variable_kind_dict
    status_dict = eval(status_dict['glpk'])
    variable_kind_dict = eval(variable_kind_dict['glpk'])

    if new_objective and new_objective != 'update problem':
        update_objective(cobra_model, new_objective)
    #Faster to use these dicts than index lists
    index_to_metabolite = dict(
        zip(range(len(cobra_model.metabolites)), cobra_model.metabolites))
    index_to_reaction = dict(
        zip(range(len(cobra_model.reactions)), cobra_model.reactions))
    reaction_to_index = dict(
        zip(index_to_reaction.values(), index_to_reaction.keys()))
    if the_problem == None or the_problem in ['return', 'setup'] or \
           not isinstance(the_problem, LPX):
        lp = LPX()  # Create empty problem instance
        lp.name = 'cobra'  # Assign symbolic name to problem
        lp.rows.add(len(cobra_model.metabolites))
        lp.cols.add(len(cobra_model.reactions))
        linear_constraints = []
        for r in lp.rows:
            the_metabolite = index_to_metabolite[r.index]
            r.name = the_metabolite.id
            b = float(the_metabolite._bound)
            c = the_metabolite._constraint_sense
            if c == 'E':
                r.bounds = b, b  # Set metabolite to steady state levels
            elif c == 'L':
                r.bounds = None, b
            elif c == 'G':
                r.bounds = b, None
            #Add in the linear constraints

            for the_reaction in the_metabolite._reaction:
                reaction_index = reaction_to_index[the_reaction]
                the_coefficient = the_reaction._metabolites[the_metabolite]
                linear_constraints.append(
                    (r.index, reaction_index, the_coefficient))
        #Need to assign lp.matrix after constructing the whole list
        lp.matrix = linear_constraints
        objective_coefficients = []

        for c in lp.cols:
            the_reaction = index_to_reaction[c.index]
            c.name = the_reaction.id
            the_reaction = index_to_reaction[c.index]
            c.kind = variable_kind_dict[the_reaction.variable_kind]
            c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
            objective_coefficients.append(
                float(the_reaction.objective_coefficient))
        #Add the new objective coefficients to the problem
        lp.obj[:] = objective_coefficients
    else:
        lp = the_problem
        #BUG with changing / unchanging the basis
        if new_objective is not None:
            objective_coefficients = []
            for c in lp.cols:  # Iterate over all rows
                the_reaction = index_to_reaction[c.index]
                c.name = the_reaction.id
                c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
                objective_coefficients.append(
                    float(the_reaction.objective_coefficient))
                c.kind = variable_kind_dict[the_reaction.variable_kind]
            #Add the new objective coefficients to the problem
            lp.obj[:] = objective_coefficients
        else:
            for c in lp.cols:  # Iterate over all rows
                the_reaction = index_to_reaction[c.index]
                c.name = the_reaction.id
                c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
                c.kind = variable_kind_dict[the_reaction.variable_kind]
    if objective_sense.lower() == 'maximize':
        lp.obj.maximize = True  # Set this as a maximization problem
    else:
        lp.obj.maximize = False
    if the_problem == 'setup':
        return lp
    if print_solver_time:
        start_time = time()
    the_methods = [1, 2, 3]
    if lp_method in the_methods:
        the_methods.remove(lp_method)
    else:
        lp_method = 1
    if not isinstance(the_problem, LPX):
        if lp.kind == int:
            lp.simplex(tol_bnd=tolerance_optimality,
                       tol_dj=tolerance_optimality,
                       meth=lp_method)  # we first have to solve the LP?
            lp.integer(tol_int=tolerance_integer)
        else:
            lp.simplex(tol_bnd=tolerance_optimality,
                       tol_dj=tolerance_optimality,
                       meth=lp_method)
        # Solve this LP or MIP with the simplex (depending on if integer variables exist).  Takes about 0.35 s without hot start
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            for lp_method in the_methods:
                lp.simplex(tol_bnd=tolerance_optimality,
                           tol_dj=tolerance_optimality,
                           meth=lp_method)
                if lp.status == 'opt':
                    if lp.kind == int:
                        lp.integer(tol_int=tolerance_integer)
                    break
    else:
        if lp.kind == int:
            lp.simplex(tol_bnd=tolerance_optimality,
                       tol_dj=tolerance_optimality,
                       meth=lp_method,
                       tm_lim=100)  # we first have to solve the LP?
            lp.integer(tol_int=tolerance_integer)
        else:
            lp.simplex(tol_bnd=tolerance_optimality,
                       tol_dj=tolerance_optimality,
                       meth=lp_method,
                       tm_lim=100)

        #If the solver takes more than 0.1 s with a hot start it is likely stuck
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            if lp.kind == int:
                lp.simplex(tol_bnd=tolerance_optimality,
                           tol_dj=tolerance_optimality,
                           meth=lp_method)  # we first have to solve the LP?
                lp.integer(tol_int=tolerance_integer)
            else:
                for lp_method in the_methods:
                    lp.simplex(tol_bnd=tolerance_optimality,
                               tol_dj=tolerance_optimality,
                               meth=lp_method)
                    if lp.status == 'opt':
                        if lp.kind == int:
                            lp.integer(tol_int=tolerance_integer)
                        break
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            lp = optimize_glpk(
                cobra_model,
                new_objective=new_objective,
                objective_sense=objective_sense,
                min_norm=min_norm,
                the_problem=None,
                print_solver_time=print_solver_time,
                tolerance_optimality=tolerance_optimality,
                tolerance_feasibility=tolerance_feasibility)['the_problem']
            if lp.status == 'opt':
                if lp.kind == int:
                    lp.integer(tol_int=tolerance_integer)

        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            lp.simplex(tol_bnd=tolerance_optimality,
                       presolve=True,
                       tm_lim=5000)
            if lp.kind == int:
                lp.integer(tol_int=tolerance_integer)

    if print_solver_time:
        print 'simplex time: %f' % (time() - start_time)
    x = []
    y = []
    x_dict = {}
    y_dict = {}
    if lp.status in status_dict:
        status = status_dict[lp.status]
    else:
        status = 'failed'
    if status == 'optimal':
        objective_value = lp.obj.value
        [(x.append(float(c.primal)), x_dict.update({c.name: c.primal}))
         for c in lp.cols]

        if lp.kind == float:
            #return the duals as well as the primals for LPs
            [(y.append(float(c.dual)), y_dict.update({c.name: c.dual}))
             for c in lp.rows]
        else:
            #MIPs don't have duals
            y = y_dict = None
        x = array(x)

    else:
        x = y = x_dict = y_dict = objective_value = None
        if error_reporting:
            print 'glpk failed: %s' % lp.status
    cobra_model.solution = the_solution = Solution(objective_value,
                                                   x=x,
                                                   x_dict=x_dict,
                                                   y=y,
                                                   y_dict=y_dict,
                                                   status=status)
    solution = {'the_problem': lp, 'the_solution': the_solution}

    return solution
Esempio n. 26
0
def _optimize_glpk(cobra_model, new_objective=None, objective_sense='maximize',
                  min_norm=0, the_problem=None, 
                  tolerance_optimality=1e-6, tolerance_feasibility=1e-6, tolerance_integer=1e-9,
                  error_reporting=None, print_solver_time=False,
                 lp_method=1, quadratic_component=None,
                  reuse_basis=True,
                  #Not implemented
                  tolerance_barrier=None, lp_parallel=None,
                  copy_problem=None, relax_b=None,update_problem_reaction_bounds=True):
    """Uses the GLPK (www.gnu.org/software/glpk/) optimizer via pyglpk
    (http://www.tfinley.net/software/pyglpk/release.html) to perform an optimization
    on cobra_model for the objective_coefficients in cobra_model._objective_coefficients
    based on the objective sense.

    cobra_model: A cobra.Model object

    new_objective: Reaction, String, or Integer referring to a reaction in
    cobra_model.reactions to set as the objective.  Currently, only supports single
    objective coeffients.  Will expand to include mixed objectives.

    objective_sense: 'maximize' or 'minimize'

    min_norm: not implemented

    the_problem: None or a problem object for the specific solver that can be used to hot
    start the next solution.

    tolerance_optimality: Solver tolerance for optimality.

    tolerance_feasibility: Solver tolerance for feasibility.

    error_reporting: None or True to disable or enable printing errors encountered
    when trying to find the optimal solution.
    
    print_solver_time: False or True.  Indicates if the time to calculate the solution
    should be displayed.

    quadratic_component: None.  GLPK cannot solve quadratic programs at the moment.

    reuse_basis: Boolean.  If True and the_problem is a model object for the solver,
    attempt to hot start the solution.  Currently, only True is available for GLPK

    
    update_problem_reaction_bounds: Boolean.  Set to True if you're providing the_problem
    and you've modified reaction bounds on your cobra_model since creating the_problem.  Only
    necessary for CPLEX
    
    lp.simplex() with Salmonella model:
         cold start: 0.42 seconds
         hot start: 0.0013 seconds
    """

    from numpy import zeros, array, nan
    #TODO: Speed up problem creation
    if hasattr(quadratic_component, 'todok'):
        raise Exception('GLPK cannot solve quadratic programs please '+\
                        'try using the gurobi or cplex solvers')

    from glpk import LPX
    from cobra.flux_analysis.objective import update_objective
    from cobra.solvers.legacy import status_dict, variable_kind_dict
    status_dict = eval(status_dict['glpk'])
    variable_kind_dict = eval(variable_kind_dict['glpk'])

    if new_objective and new_objective != 'update problem':
        update_objective(cobra_model, new_objective)
    #Faster to use these dicts than index lists
    index_to_metabolite = dict(zip(range(len(cobra_model.metabolites)),
                                   cobra_model.metabolites))
    index_to_reaction = dict(zip(range(len(cobra_model.reactions)),
                                 cobra_model.reactions))
    reaction_to_index = dict(zip(index_to_reaction.values(),
                                 index_to_reaction.keys()))
    if the_problem == None or the_problem in ['return', 'setup'] or \
           not isinstance(the_problem, LPX):
        lp = LPX()        # Create empty problem instance
        lp.name = 'cobra'     # Assign symbolic name to problem
        lp.rows.add(len(cobra_model.metabolites))
        lp.cols.add(len(cobra_model.reactions))
        linear_constraints = []
        for r in lp.rows:
            the_metabolite = index_to_metabolite[r.index]
            r.name = the_metabolite.id
            b = float(the_metabolite._bound)
            c = the_metabolite._constraint_sense
            if c == 'E':
                r.bounds = b, b     # Set metabolite to steady state levels
            elif c == 'L':
                r.bounds = None, b
            elif c == 'G':
                r.bounds = b, None
            #Add in the linear constraints

            for the_reaction in the_metabolite._reaction:
                reaction_index = reaction_to_index[the_reaction]
                the_coefficient = the_reaction._metabolites[the_metabolite]
                linear_constraints.append((r.index, reaction_index,
                                           the_coefficient))
        #Need to assign lp.matrix after constructing the whole list
        lp.matrix = linear_constraints
        objective_coefficients = []

        for c in lp.cols:
            the_reaction = index_to_reaction[c.index]
            c.name = the_reaction.id           
            the_reaction = index_to_reaction[c.index]
            c.kind = variable_kind_dict[the_reaction.variable_kind]
            c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
            objective_coefficients.append(float(the_reaction.objective_coefficient))
        #Add the new objective coefficients to the problem
        lp.obj[:] = objective_coefficients
    else:
        lp = the_problem
        #BUG with changing / unchanging the basis
        if new_objective is not None:
            objective_coefficients = []
            for c in lp.cols:      # Iterate over all rows
                the_reaction = index_to_reaction[c.index]
                c.name = the_reaction.id
                c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
                objective_coefficients.append(float(the_reaction.objective_coefficient))
                c.kind = variable_kind_dict[the_reaction.variable_kind]
            #Add the new objective coefficients to the problem
            lp.obj[:] = objective_coefficients
        else:
            for c in lp.cols:      # Iterate over all rows
                the_reaction = index_to_reaction[c.index]
                c.name = the_reaction.id
                c.bounds = the_reaction.lower_bound, the_reaction.upper_bound
                c.kind = variable_kind_dict[the_reaction.variable_kind]
    if objective_sense.lower() == 'maximize':
        lp.obj.maximize = True # Set this as a maximization problem
    else:
        lp.obj.maximize = False
    if the_problem == 'setup':
        return lp
    if  print_solver_time:
        start_time = time()
    the_methods = [1, 2, 3]
    if lp_method in the_methods:
        the_methods.remove(lp_method)
    else:
        lp_method = 1
    if not isinstance(the_problem, LPX):
       if lp.kind == int:
           lp.simplex(tol_bnd=tolerance_optimality, tol_dj=tolerance_optimality, meth=lp_method)  # we first have to solve the LP?
           lp.integer(tol_int=tolerance_integer)
       else:
           lp.simplex(tol_bnd=tolerance_optimality, tol_dj=tolerance_optimality, meth=lp_method)
       # Solve this LP or MIP with the simplex (depending on if integer variables exist).  Takes about 0.35 s without hot start
       if lp.status in status_dict:
           status = status_dict[lp.status]
       else:
           status = 'failed'
       if status != 'optimal':
           for lp_method in the_methods:
               lp.simplex(tol_bnd=tolerance_optimality, tol_dj=tolerance_optimality, meth=lp_method)
               if lp.status == 'opt':
                   if lp.kind == int:
                       lp.integer(tol_int=tolerance_integer)
                   break
    else:
        if lp.kind == int:
            lp.simplex(tol_bnd=tolerance_optimality, tol_dj=tolerance_optimality, meth=lp_method, tm_lim=100)  # we first have to solve the LP?
            lp.integer(tol_int=tolerance_integer)
        else:
            lp.simplex(tol_bnd=tolerance_optimality, tol_dj=tolerance_optimality, meth=lp_method, tm_lim=100)
       
        #If the solver takes more than 0.1 s with a hot start it is likely stuck
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            if lp.kind == int:
               lp.simplex(tol_bnd=tolerance_optimality, tol_dj=tolerance_optimality, meth=lp_method)  # we first have to solve the LP?
               lp.integer(tol_int=tolerance_integer)
            else:
               for lp_method in the_methods:
                   lp.simplex(tol_bnd=tolerance_optimality, tol_dj=tolerance_optimality, meth=lp_method)
                   if lp.status == 'opt':
                       if lp.kind == int:
                           lp.integer(tol_int=tolerance_integer) 
                       break
        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            lp = optimize_glpk(cobra_model, new_objective=new_objective,
                               objective_sense=objective_sense,
                               min_norm=min_norm, the_problem=None,
                               print_solver_time=print_solver_time,
                               tolerance_optimality=tolerance_optimality,
                               tolerance_feasibility=tolerance_feasibility)['the_problem']
            if lp.status == 'opt':
                if lp.kind == int:
                    lp.integer(tol_int=tolerance_integer)

        if lp.status in status_dict:
            status = status_dict[lp.status]
        else:
            status = 'failed'
        if status != 'optimal':
            lp.simplex(tol_bnd=tolerance_optimality, presolve=True, tm_lim=5000)
            if lp.kind == int:
                lp.integer(tol_int=tolerance_integer)

    if print_solver_time:
        print 'simplex time: %f'%(time() - start_time)
    x = []
    y = []
    x_dict = {}
    y_dict = {}
    if lp.status in status_dict:
        status = status_dict[lp.status]
    else:
        status = 'failed'
    if status == 'optimal':
        objective_value = lp.obj.value
        [(x.append(float(c.primal)),
          x_dict.update({c.name:c.primal}))
          for c in lp.cols]
        
        if lp.kind == float:
            #return the duals as well as the primals for LPs
            [(y.append(float(c.dual)),
              y_dict.update({c.name:c.dual}))
             for c in lp.rows]
        else:
            #MIPs don't have duals
            y = y_dict = None
        x = array(x)
            
    else:
        x = y = x_dict = y_dict = objective_value = None
        if error_reporting:
            print 'glpk failed: %s'%lp.status
    the_solution = Solution(objective_value, x=x, x_dict=x_dict,
                            y=y, y_dict=y_dict,
                            status=status)
    solution = {'the_problem': lp, 'the_solution': the_solution}

    return solution
Esempio n. 27
0
 def setUp(self):
     self.lp = LPX()
     self.r = self.lp.rows
     self.c = self.lp.cols
     self.r.add(5)
     self.c.add(4)
Esempio n. 28
0
 def setUp(self):
     self.lp = LPX()
     self.vc = self.lp.cols  # Vector collection is the column list.
     self.moreSetUp()
Esempio n. 29
0
 def setUp(self):
     self.lp = LPX()
     self.vc = self.lp.rows  # Vector collection is the row list.
     self.moreSetUp()
Esempio n. 30
0
 def setUp(self):
     self.lp = LPX()
Esempio n. 31
0
    def setUp(self):
        self.lp = LPX()
        param_names = [n for n in dir(self.lp.params) if n[0] != '_']
        param_names.remove('reset')
        self.param_name2default = dict([(n, getattr(self.lp.params, n))
                                        for n in param_names])

        # INTEGER PARAMETER VALUES

        # Have nice lists of, for each parameter, valid values, and
        # values illegal because they are of bad type or value.
        p2v, p2bt, p2bv = {}, {}, {}
        # These have legal values 0, 1
        for n in 'price'.split():
            p2v[n] = 0, 1
            p2bv[n] = -100, -1, 2, 3, 4, 5
        # These have legal values 0, 1,2
        for n in 'branch mpsobj'.split():
            p2v[n] = 0, 1, 2
        # These have legal values 0, 1,2, 3
        for n in 'msglev scale btrack'.split():
            p2v[n] = 0, 1, 2, 3
        # These all have the following illegal typed values.
        illegals = 'hi!', [1], {2: 5}, 0.5, complex(1, 0), self.lp
        for n in p2v:
            p2bt[n] = illegals
        # Set their illegal values.
        illegal_vals = -100, -1, 2, 3, 4, 5, 1000
        for n in p2v:
            legals = set(p2v[n])
            p2bv[n] = tuple([v for v in illegal_vals if v not in legals])
        # These may be any positive integer.
        for n in 'outfrq'.split():
            p2v[n] = 1, 2, 3, 100, 1600, 80000, 4000000, 2000000000
            p2bt[n] = illegals
            p2bv[n] = 0, -1, -2, -3, -100, -100000
        # These may be any integer.
        for n in 'itlim'.split():
            p2v[n] = illegal_vals
            p2bt[n] = illegals
        # Integer in range 255.
        for n in 'usecuts'.split():
            p2v[n] = range(0, 0x100)
            p2bt[n] = illegals
            p2bv[n] = tuple(range(-10, 0)) + tuple(range(0x100, 0x110))

        # FLOAT PARAMETER VALUES

        # Previous illegal types included floats.
        illegals = tuple([iv for iv in illegals if type(iv) != float])
        # Floats without bound.
        for n in 'objll objul outdly tmlim'.split():
            p2v[n] = -1e100, -5.23e20, -2.231, -1, 0, 0.5, 1, 3.14159, 1e100
            p2bt[n] = illegals
        # Bounded in [0, 1] range.
        for n in 'relax'.split():
            p2v[n] = 0, .2, .45678, .901, 1
            p2bv[n] = -5e6, -1, -0.01, 1.01, 1.5, 1000
            p2bt[n] = illegals
        # Bounded in double-epsilon to 0.001 range.
        for n in 'tolbnd toldj tolint tolobj tolpiv'.split():
            p2v[n] = 2.3e-16, 1e-8, 0.000523, 0.001
            p2bv[n] = -1000, -1e-8, 0, 0.0011, 0.1, 5.123, 1e100
            p2bt[n] = illegals

        # BOOLEAN PARAMETER VALUES

        # These have boolean values.  They have no illegal values
        # owing to PyGLPK's pecularity of having boolean values set to
        # the bool(value) of value, which is always defined.
        bname = 'dual mpsfree mpsinfo mpsorig mpsskip mpswide presol round'
        for n in bname.split():
            p2v[n] = False, True

        # Set up the mapping from parameter names to tuples of legal
        # values, and illegal params because of value and type.
        self.param_name2values = p2v
        self.param_name2bad_values = p2bv
        self.param_name2bad_type_values = p2bt
Esempio n. 32
0
from glpk import LPX

# set up to maximize the objective function
lp = LPX()
lp.name = 'foobartendr'
lp.obj.maximize = True

# append 3 rows
row_names = ["ingrednt", "bartendr", "delivery"]
lp.rows.add(len(row_names))

for r in lp.rows:
    r.name = row_names[r.index]

lp.rows[0].bounds = None, 100.0
lp.rows[1].bounds = None, 600.0
lp.rows[2].bounds = None, 150.0

# append 3 cols, named x0, x1, x2
lp.cols.add(3)

for c in lp.cols:
    c.name = 'x%d' % c.index
    c.bounds = 0.0, None

# set the objective coefficients and
# non-zero entries of the constraint matrix
lp.obj[:] = [ 5.0, 3.0, 2.0 ]
lp.matrix = [ 1.0, 1.0, 3.0, 10.0, 4.0, 5.0, 1.0, 1.0, 3.0 ]

# report the objective function value and structural variables
Esempio n. 33
0
 def testObjectiveName(self):
     lp = LPX()
     with self.assertRaises(ValueError) as cm:
         lp.obj.name = 'a' * 256
     self.assertIn('name may be at most 255 chars', str(cm.exception))
Esempio n. 34
0
 def testLpxStatus(self):
     lp = LPX()
     self.assertEqual('undef', lp.status_s)
Esempio n. 35
0
 def testObjectiveShift(self):
     lp = LPX()
     with self.assertRaises(TypeError) as cm:
         del(lp.obj.shift)
     self.assertIn('deletion not supported', str(cm.exception))