Your linearization is not quite correct. It should be
(1a) a - c >= 0
(1b) b - c >= 0
(2) a + b - c <= 1
You can use general constraints to model this. Gurobi supports, among others, the AND
constraint for binary variables, see
http://www.gurobi.com/documentation/8.0/refman/constraints.html
See also the "genconstr" example, for example in Python:
http://www.gurobi.com/documentation/8.0/examples/genconstr_py.html
In your case, you would for example do:
m = Model("mymodel")
a = m.addVar(vtype=GRB.BINARY, name="a")
b = m.addVar(vtype=GRB.BINARY, name="b")
c = m.addVar(vtype=GRB.BINARY, name="c")
m.addConstr(c == and_(a,b))
If you only need the auxiliary variables (in your case, c) to model the objective
function, then, in your linearization, you only need either constraints (1a) and (1b) or
constraint (2), depending on the sign of the objective coefficient. For example, if you
want to minimize c, then you only need (2) because if one of a or b is zero, then there is
no reason for c to be one. It will automatically be pushed down to zero due to the
objective function. This trick is already automatically included when you use the AND
constraint of Gurobi. It will detect that (1a) and (1b) are not needed and only use (2)
for its internal linearization.
Gurobi usually performs pretty well on pure binary problems. But there are
counter-examples. For example, SAT problems are also just binary problems, but because
there the solution to set all variables to 0.5 will always satisfy all constraints in the
MIP formulation, the LP relaxation is pretty useless and thus, you will most of the time
be much faster by using a SAT solver instead. But if you have a meaningful objective
function or more complex constraints (like knapsack constraints) then Gurobi should
usually be a very good choice.
Regards,
Tobias