import math
import numpy as np
import pandas as pd
from docplex.cp.model import CpoModel
def solve_toys_selling_problem(out_nb, input_nb_toys, each_capacity, min_acceptable_yield, solve_time_limit, yield_constraint, max_nb_bins):
print(f"Solving problem {out_nb}")
# Load toy data from Excel file
toys_df = pd.read_excel('out1.xlsx', index_col=0)
toys_df = toys_df.filter(['toy', 'toyType', 'max_life', 'weight']).head(input_nb_toys)
nb_toys = len(toys_df.index)
max_nb_bins = max_nb_bins
bins_capacity = np.array([each_capacity] * max_nb_bins)
all_toys_weight = toys_df['weight'].to_numpy()
all_toys_max_life_ub = toys_df['max_life'].to_numpy()
all_toys_max_life_lb = all_toys_max_life_ub * min_acceptable_yield
all_toys_max_life_lb_min = math.floor(np.min(all_toys_max_life_lb))
all_toys_max_life_ub_max = math.ceil(np.max(all_toys_max_life_ub))
mdl = CpoModel('ToysSelling')
bin_toy_var = [[mdl.interval_var(optional=True, size=all_toys_weight[toy], name=f"b{bin}-t{toy}")
for toy in range(nb_toys)] for bin in range(max_nb_bins)]
bin_sell_var = [
mdl.integer_var(min=all_toys_max_life_lb_min, max=all_toys_max_life_ub_max, name=f"b{bin}-sell")
for bin in range(max_nb_bins)]
# Constraint 1: One toy in one bin
for toy in range(nb_toys):
mdl.add(mdl.sum([mdl.presence_of(bin_toy_var[bin][toy]) for bin in range(max_nb_bins)]) == 1)
# Constraint 2: Capacity
for bin in range(max_nb_bins):
mdl.add(mdl.sum([mdl.size_of(bin_toy_var[bin][toy]) for toy in range(nb_toys)]) <= bins_capacity[bin])
# Constraint 3: Set yield threshold
if yield_constraint:
for bin in range(max_nb_bins):
for toy in range(nb_toys):
mdl.add(mdl.if_then(mdl.presence_of(bin_toy_var[bin][toy]) == 1,
mdl.in_range(bin_sell_var[bin], all_toys_max_life_lb[toy],
all_toys_max_life_ub[toy])))
# Objective: Minimize the number of bins used
mdl.add(mdl.minimize(mdl.sum([mdl.logical_or([mdl.presence_of(bin_toy_var[bin][toy]) for toy in range(nb_toys)])
for bin in range(max_nb_bins)])))
# Solve the model
solution = mdl.solve(TimeLimit=solve_time_limit)
# Print solution status
print(f"Solution status: {solution.get_solve_status()}")
# Return the solution if feasible
if solution.is_solution():
return solution
else:
return None
# Example usage:
result = solve_toys_selling_problem(out_nb=1, input_nb_toys=10, each_capacity=50, min_acceptable_yield=0.8,
solve_time_limit=10, yield_constraint=True, max_nb_bins=5)
# Additional processing or output based on the result can be added here
------------------------------
Tamrat Workineh
------------------------------
Original Message:
Sent: Wed December 06, 2023 06:05 AM
From: sandeep singh chauhan
Subject: Constraint not working
Hi
Thanks for your response. I have to use interval variables as I have some constraints that need intervals. I am attaching the model. It is not giving optimal. Could you support on same.
'''
Toys Selling Problem:
Toys are to be placed in bins. These bins are to be sold.
Each toy has a weight, and max life.
Each bin has a capacity.
Each toy should be in one bin only.
The weights of the toys in the bin should not exceed the capacity of the bin.
The time the bin can be sold at max is the minimum of the max life of the toys in the bin. We need to maximize life utilization.
'''
import math
import numpy as np
import pandas as pd
from docplex.cp.model import CpoModel
def main(
out_nb,
input_nb_toys,
each_capacity,
min_acceptable_yield,
solve_time_limit,
yield_constraint,
max_nb_bins,
):
print(f"Solving problem {out_nb}")
toys_df = pd.read_excel(r'out1.xlsx', index_col=0)
toys_df = toys_df.filter(['toy', 'toyType', 'max_life', 'weight'])
toys_df = toys_df.head(input_nb_toys)
nb_toys = len(toys_df.index)
max_nb_bins = max_nb_bins
bins_capacity = np.array([each_capacity] * max_nb_bins)
all_toys_weight = toys_df['weight'].to_numpy()
all_toys_maxLife_ub = toys_df['max_life'].to_numpy()
all_toys_maxLife_lb = all_toys_maxLife_ub * min_acceptable_yield
all_toys_maxLife_lb_min = math.floor(np.min(all_toys_maxLife_lb))
all_toys_maxLife_ub_max = math.ceil(np.max(all_toys_maxLife_ub))
mdl = CpoModel('WP')
bin_toy_var = [[mdl.interval_var(optional=True, size=all_toys_weight[toy], name="b{}-t{}".format(bin, toy))
for toy in range(nb_toys)] for bin in range(max_nb_bins)]
bin_sell_var = [
mdl.integer_var(min=all_toys_maxLife_lb_min, max=all_toys_maxLife_ub_max, name="b{}-sell".format(bin))
for bin in range(max_nb_bins)]
# constraint 1: one toy in one bin
for toy in range(nb_toys):
mdl.add(mdl.sum([mdl.presence_of(bin_toy_var[bin][toy]) for bin in range(max_nb_bins)]) == 1)
# constraint 2: capacity
for bin in range(max_nb_bins):
mdl.add(
mdl.sum([mdl.size_of(bin_toy_var[bin][toy]) for toy in range(nb_toys)]) <= bins_capacity[bin])
# constraint 3: set yield threshold
if yield_constraint:
for bin in range(max_nb_bins):
for toy in range(nb_toys):
mdl.add(mdl.if_then(mdl.presence_of(bin_toy_var[bin][toy]) == 1,
mdl.in_range(bin_sell_var[bin], all_toys_maxLife_lb[toy],
all_toys_maxLife_ub[toy])))
# objective
mdl.add(mdl.minimize(mdl.sum(
[mdl.logical_or([mdl.presence_of(bin_toy_var[bin][toy]) for toy in range(nb_toys)]) for bin in
range(max_nb_bins)])))
Attaching data also. Thank you
------------------------------
sandeep singh chauhan
Original Message:
Sent: Tue December 05, 2023 04:17 AM
From: GUGLIELMO SANCHINI
Subject: Constraint not working
Hi Sandeep, it would be useful if you posted the whole code, or at least the code related to the variables/dictionaries
- bin_task_var
- bin_ex_intvl_var
- all_task_interval_var
However, it looks like you want to restrict an interval varia