I'm working on an Task Scheduling problem given in Table 3 of paper Holistic energy awareness for intelligent drones.
In the 6th equation: N_d = E_d/B_d
I want to convert floating value of (E_d/B_d) to an integer value of N_d. I'm using an Abstract model on pyomo (6.4.0) on python 3.7 and glpk 4.65 solver
The basic original code written is
model.Drones = Set() # List of drones
model.Battery_capacity = Param(model.Drones, within=NonNegativeReals) # =170
model.Energy_total = Var(model.Drones, within=NonNegativeReals, initialize=1)
model.Charging_sessions = Var(model.Drones, within=NonNegativeReals, initialize=1)
def battery_charging_sessions_rule(model, d):
return model.Charging_sessions[d] == (model.Energy_total[d]/model.Battery_capacity[d])
model.battery_charging_sessions = Constraint(model.Drones, rule=battery_charging_sessions_rule)
In this case, model.battery_charging_sessions is a floating point value which can be less than 1 also. I've tried various options like
model.Charging_sessions = Var(model.Drones, within=Integers, initialize=1, bounds=(0,None))
and using the following return statement also instead of previous one
return model.Charging_sessions[d] == floor(value((model.Energy_total[d]/model.Battery_capacity[d])))
However, this cause the model.Charging_sessions
forced to be 0 and it wont even be generated in results file. Using the logs I found out with no change in original code,
Charging_sessions[d] - (0.0058823530*Energy_total[d])
is lower and upper bounded by 0,where 0.0058823530 = 1/170.
While with the changes the lower and upper bound of
Charging_sessions[d]
are 0. It seems that by using floor(value()) or int(value()) the term (0.0058823530*Energy_total[d])
is reduced to 0.
What are the ways I can get the integer value?
A lot of thanks to Erwin Kalvelagen for providing the solution. This answer can work for both converting a float value to int or taking floor and taking ceil. I've modified my code to take floor of the value. Here is the solution
model.Drones = Set() # List of drones
model.Battery_capacity = Param(model.Drones, within=NonNegativeReals) # =170
model.Energy_total = Var(model.Drones, within=NonNegativeReals, initialize=1)
model.Charging_sessions = Var(model.Drones, within=NonNegativeIntegers, initialize=0, bounds=(0,None))
model.Charging_sessionsTmp = Var(model.Drones, within=NonNegativeReals, initialize=1, bounds=(0,None))
def battery_charging_sessions_rule(model, d):
return model.Charging_sessionsTmp[d] == model.Energy_total[d]/model.Battery_capacity[d])
model.battery_charging_sessions = Constraint(model.Drones, rule=battery_charging_sessions_rule)
def batt_charging_floor_val_rule_lb(model_in,d):
return model_in.Charging_sessionsTmp[d] - 0.9999 <= model_in.Charging_sessions[d]
model.battery_charging_sessions_int_lb = Constraint(model.Drones, rule=batt_charging_floor_val_rule_lb)
def batt_charging_floor_val_rule_ub(model_in,d):
return model_in.Charging_sessions[d] <= model_in.Charging_sessionsTmp[d]
The 3 constraints in the code basically implement following constraint
(E_d/B_d) - 0.9999 <= N_d <= (E_d/B_d)