Lextree
Simply the best software for managing legal entities and documents.

The Berkman Letter
Practical analysis and commentary for business, law, and more.

# Python Gurobi MILP no errors but not a sensible solution?

Hi, I wrote a code in Gurobi Python API for minimizing production costs which have a variable and a fixed cost part. There are a number of tasks which are assigned to a number of stations whereby cycle time should not be exceeded. Also 4 types of machines are given which the program should evaluate which ones are being used, the machines with higher var. costs have higher fixed costs and vice versa. The part with different types of machines is making me the most headaches, because the duration and the cost of assigning a task is not dependent on the station indices but only on the machine typ. I dont know the problem but the program gives no errors but also not really a solution is calculated. I think the problem might be that the constraints are not programmed correctly so that they dont have a impact on the Optimization Model. Also it could be that my objective function is not on target. I posted my code below.

It says optimal solution found but obviously there is not really a solution. I would really appreciate your help. My code is as follows:

It says optimal solution found but obviously there is not really a solution. I would really appreciate your help. My code is as follows:

import gurobipy as gp

from gurobipy import GRB, quicksum stations = [1,2,3,4] tasks = ['w01','w02','w03'] durations = {('w01','BTC1'):200, ('w02','BTC1'):500, ('w03','BTC1'):300, ('w01','BTC2'):100, ('w02','BTC2'):250, ('w03','BTC2'):150 } successors = {'w01':[],'w02':['w01'],'w03':['w01']} types = ['BTC1','BTC2'] arcs = [(i,j) for i in tasks for j in types] arcs2 = [(i,j) for i in stations for j in tasks] C = 500 C_min = 100 edges, v_cost, f_cost = gp.multidict({ ('BTC1','w01'): [150,200000], ('BTC1','w02'): [200,200000], ('BTC1','w03'): [180,200000], ('BTC2','w01'): [120,300000], ('BTC2','w02'): [160,300000], ('BTC2','w03'): [100,300000] }) m = gp.Model() y = m.addVars(stations, vtype=GRB.BINARY, name='y') x = m.addVars(arcs, vtype=GRB.CONTINUOUS, name='x',lb=0,ub=1) # Variable for share of assignment between 0 and 1 a = m.addVars(arcs2, vtype=GRB.CONTINUOUS, name='a',lb=0,ub=1) # every task is exactly done by a share of 1, so every task is fully completed over the number of stations m.addConstrs(quicksum(a[i,j] for j in tasks) == 1 for i in stations) #Capacity constraint m.addConstrs(quicksum(durations[i,j]*x[i,j] for i in tasks for j in types) <= C*y[j] for j in stations) # there is also a minimum Capacity m.addConstrs(quicksum(durations[i,j]*x[i,j] for i in tasks for j in types) >= C_min*y[j] for j in stations) # precedence constraints m.addConstrs(quicksum(p*x[k,j] for j in types for p in stations) >= quicksum(p*x[i,j] for j in types for p in stations) for k in tasks for i in successors[k] if k!= 'w01') m.setObjective(x.prod(v_cost)+y.prod(f_cost), GRB.MINIMIZE) m.optimize() m.optimize() only returns: Gurobi Optimizer version 9.5.2 build v9.5.2rc0 (win64) Thread count: 2 physical cores, 4 logical processors, using up to 4 threads Optimize a model with 14 rows, 22 columns and 76 nonzeros Model fingerprint: 0x4cbb069e Variable types: 18 continuous, 4 integer (4 binary) Coefficient statistics: Matrix range [1e+00, 5e+02] Objective range [0e+00, 0e+00] Bounds range [1e+00, 1e+00] RHS range [1e+00, 1e+00] Presolve removed 11 rows and 16 columns Presolve time: 0.01s Presolved: 3 rows, 6 columns, 14 nonzeros Variable types: 6 continuous, 0 integer (0 binary) Root relaxation: objective 0.000000e+00, 0 iterations, 0.01 seconds (0.00 work units) Nodes | Current Node | Objective Bounds | Work Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time * 0 0 0 0.0000000 0.00000 0.00% - 0s Explored 1 nodes (0 simplex iterations) in 0.12 seconds (0.00 work units) Thread count was 4 (of 4 available processors) Solution count 1: 0 Optimal solution found (tolerance 1.00e-04) Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0000%