Global AI and Data Science

 View Only
  • 1.  Constraint not working

    Posted Tue December 05, 2023 02:57 AM

    Hi I have a constraint that is not working as per the expectation. what could be the ideal way to code the following constraint. TIA

    for bin in range(max_nb_bins):
    for task in range(nb_tasks):
    mdl.add(mdl.if_then(mdl.presence_of(bin_task_var[bin][task]) != 0,
    mdl.in_range(bin_ex_intvl_var[bin], all_task_interval_lb[task],
    all_task_interval_ub[task])))


    ------------------------------
    sandeep singh chauhan
    ------------------------------

    #AIandDSSkills


  • 2.  RE: Constraint not working

    Posted Tue December 05, 2023 12:09 PM

    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 variable to lie between a task-dependent start and end, only when the variable is present of course. If this is the case, I suggest you use the span constraint (span_constraint) in the following way:

    for bin in range(max_nb_bins):
    mdl.add(
    mdl.span(bin_ex_intvl_var[bin], [bin_task_var[bin][task] for task in range(nb_tasks)])
    )

    where the interval variables 

    bin_task_var[bin][task]

    when defined, will have start and end limited by all_task_interval_lb and all_task_interval_ub, for example:

    bin_task_var[bin][task] = mdl.interval_var(
    start=[all_task_interval_lb[task], INTERVAL_MAX],
    end=[all_task_interval_lb[task], all_task_interval_ub[task]])


    ------------------------------
    GUGLIELMO SANCHINI
    ------------------------------



  • 3.  RE: Constraint not working

    Posted Wed December 06, 2023 06:06 AM
      |   view attached

    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
    ------------------------------

    Attachment(s)

    xlsx
    out1 (1).xlsx   9 KB 1 version


  • 4.  RE: Constraint not working

    Posted Wed December 06, 2023 09:58 AM

    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
    ------------------------------