I am working on a format of resource optimization problem and writing a GEKKO code to solve. Problem statement is as follows: Let assume there are 2 workers and 4 tasks. Each worker gets some rewards for the tasks it picks. Each task can be assigned to only one worker and each worker can only pick one tasks. The objective is to maximize the total rewards obtained by both workers.
As per the requirement of problem decision variables are as follows:
- An 0-1 allocation matrix that decides which task to be assigned to which worker
- A weights array, that assign relative weights to each task.
Reward given to worker is calculated based on the ratio of weights of task picked and sum of weights of all tasks allocated to worker.
Following is the code for same:
import numpy as np
from gekko import GEKKO
rewards = np.array([[2,5,8,10],[1,5,7,11]])
m = GEKKO(remote=False)
allocation = m.Array(m.Var,(2,4),lb=0,ub=1, integer=True)
weights = m.Array(m.Var,4,lb=0,ub=1)
def reward(allocation, weights, rewards):
temp=np.copy(allocation)
#sum_ = np.sum(weights)
for i in range(allocation.shape[1]):
temp[:, i] *= weights[i]#/sum_
total_rewards = np.sum(temp.flatten() * rewards.flatten())
return total_rewards
for j in range(4):
m.Equation(m.sum(allocation[:,j])<=1)
m.Maximize(reward(allocation, weights, rewards))
m.options.SOLVER = 1 # change solver (1=APOPT,3=IPOPT)
#m.open_folder()
m.solve()
print('allocation', allocation)
print('weights', weights)
print('Objective: ' + str(m.options.objfcnval))
In the reward function, I have commented "sum_" variable. In this case the output is:
----------------------------------------------------------------
APMonitor, Version 1.0.1
APMonitor Optimization Suite
----------------------------------------------------------------
--------- APM Model Size ------------
Each time step contains
Objects : 0
Constants : 0
Variables : 16
Intermediates: 0
Connections : 0
Equations : 5
Residuals : 5
Number of state variables: 16
Number of total equations: - 4
Number of slack variables: - 4
---------------------------------------
Degrees of freedom : 8
----------------------------------------------
Steady State Optimization with APOPT Solver
----------------------------------------------
Iter: 1 I: 0 Tm: 0.00 NLPi: 4 Dpth: 0 Lvs: 3 Obj: -1.63E+01 Gap: NaN
--Integer Solution: 0.00E+00 Lowest Leaf: -1.63E+01 Gap: 2.00E+00
Iter: 2 I: 0 Tm: 0.00 NLPi: 2 Dpth: 1 Lvs: 2 Obj: 0.00E+00 Gap:
2.00E+00
Iter: 3 I: 0 Tm: 0.00 NLPi: 3 Dpth: 1 Lvs: 4 Obj: -2.60E+01 Gap: 2.00E+00
--Integer Solution: -2.60E+01 Lowest Leaf: -2.60E+01 Gap: 0.00E+00
Iter: 4 I: 0 Tm: 0.00 NLPi: 1 Dpth: 2 Lvs: 4 Obj: -2.60E+01 Gap: 0.00E+00
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 1.729999999224674E-002 sec
Objective : -26.0000000000000
Successful solution
---------------------------------------------------
allocation [[[1.0] [1.0] [1.0] [0.0]]
[[0.0] [0.0] [0.0] [1.0]]]
weights [[1.0] [1.0] [1.0] [1.0]]
Objective: -26.0
But if i uncomment "sum_" variable i.e use ratio of weights and total weights of task allocated to worker. I am getting objective value as nan
----------------------------------------------------------------
APMonitor, Version 1.0.1
APMonitor Optimization Suite
----------------------------------------------------------------
--------- APM Model Size ------------
Each time step contains
Objects : 0
Constants : 0
Variables : 16
Intermediates: 0
Connections : 0
Equations : 5
Residuals : 5
Number of state variables: 16
Number of total equations: - 4
Number of slack variables: - 4
---------------------------------------
Degrees of freedom : 8
----------------------------------------------
Steady State Optimization with APOPT Solver
----------------------------------------------
Iter: 1 I: 0 Tm: 0.01 NLPi: 2 Dpth: 0 Lvs: 0 Obj: NaN Gap: 0.00E+00
Successful solution
---------------------------------------------------
Solver : APOPT (v1.0)
Solution time : 2.390000000013970E-002 sec
Objective : NaN
Successful solution
---------------------------------------------------
allocation [[[0.0] [0.0] [0.0] [0.0]]
[[0.0] [0.0] [0.0] [0.0]]]
weights [[0.0] [0.0] [0.0] [0.0]]
Objective: nan
Please let me know how to fix this issue or any pointer to debug this.
Thanks
Set a lower bound on
sum_to avoid divide-by-zero in the denominator.The
NaNis because the default guess value is0and the summation is initially equal to zero as well. Here is a complete script that solves successfully:Here is the output: