coin-or / pulp

A python Linear Programming API
http://coin-or.github.io/pulp/
Other
2.12k stars 390 forks source link

Forgetting ==, <= or >= silently overwrites objective function #85

Closed senarclens closed 4 years ago

senarclens commented 9 years ago

Whenever one forgets ==, <= or >= in a constraint, the objective function is overwritten without warning. I suggest to issue a warning if an objective function is added to a problem that already has an objective function. Otherwise, when typing a larger model and forgetting the right hand side of a constraint, the result may be very confusing.

Test Case: import pulp a = pulp.LpVariable('f^min', lowBound=0, cat=pulp.LpContinuous) milp = pulp.LpProblem("TC", pulp.LpMinimize) milp += a milp += a >= 1 milp += 2 * a -3

Actual Result: First objective function is silently overwritten with MINIMIZE 2 * a - 3.

Expected Result: Pulp overwrites objective function but issues a warning (to avoid confusion).

dassouki commented 9 years ago

The following is a workaround if you have to add thousands of these. However, I'm not quiet sure how you would do it from Pulp itself. My only assumption would be to put a condition in LpProblem that says something along the lines of if objective is defined, return an error if an other objective has been previously defined.

import pulp as pulp

def check_constraints(prob, c_list):
    if prob.objective:
        for c in c_list:
            if '=' not in str(c):
                print 'no operator found in constraint'
                break
            else:
                prob.addConstraint(c)
    else:
        print 'Please define an objective before you define constraints'

# Simple testing
a = pulp.LpVariable('test variable', lowBound=0, cat=pulp.LpContinuous)
my_prob = pulp.LpProblem("My test problem", pulp.LpMinimize)
cons = [a >= 1, 2 * a - 3]
cons_2 = [a >= 1, 2 * a - 3 <= 10]

# test before setting objective function
check_constraints(my_prob, cons)
check_constraints(my_prob, cons_2)

# objective function:
my_prob += a

check_constraints(my_prob, cons)
print my_prob

check_constraints(my_prob, cons_2)
print my_prob
stumitchell commented 9 years ago

Ok I get it will add to todo list

ryanjoneil commented 8 years ago

I opened a pull request for this (#96).

As a PuLP user, I disagree with requiring that the user define the objective before the constraints. In complicated models I often build variables, constraints, and the coefficient set for the objective in a loop, then call LpProblem.setObjective at the end. Changing this would be inconvenient,

pchtsp commented 4 years ago

as far as I know, we have a warning in place that shows when adding a new objective. I'll close the issue.