Skip to content

Bin Packing Problem: Solver Fails to Find Solutions Requiring More Than 4 Bins #4529

Closed

Description

@busezgi

I'm using
Version: main/v9.11.42.10
Language: C#

with Solver "SCIP" on Windows 11

I added more parts to check the "Bin Packing Problem Solver"

I changed DataModel to

class DataModel
{
    **public static double[] Weights = { 48, 30, 19, 36, 36, 27, 42, 42, 36, 24, 30,33,33,33,33,33,45,45,67,27,80,44,38,77 };**
    public int NumItems = Weights.Length;
    public int NumBins = Weights.Length;
    public double BinCapacity = 100.0;
}

I expected 7-8 bins needed with the optimized result, but the Solver stucks.

I changed the DataModel like:

class DataModel
{
    public static double[] Weights = { 2378, 2177, 1882, 1256, 1329, 2203, 2203, 2203, 2203, 2203, 2203, 956, 956, 
    956, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 1506, 
    1256, 1256, 1256, 1256,1256, 1256,1256, 1256,1256, 1256,1256, 1256};
    public int NumItems = Weights.Length;
    public int NumBins = Weights.Length;
    public double BinCapacity = 6500.0;
}

I got the same result (Stucks), but if I use small number of Weights and if needed less than 5 bins the results come out.

My full code as below:

using Google.OrTools.LinearSolver;

// https://developers.google.com/optimization/pack/bin_packing?hl=en#c

class DataModel
{
    public static double[] Weights = { 48, 30, 19, 36, 36, 27, 42, 42, 36, 24, 30,33,33,33,33,33,45,45,67,27,80,44,38,77 };
    public int NumItems = Weights.Length;
    public int NumBins = Weights.Length;
    public double BinCapacity = 100.0;
}

class Program
{
    static void Main(string[] args)
    {
        DataModel data = new DataModel();
        double saw = 6.0;
        Console.WriteLine("Optimization started!");
        // add saw thickness
        for (int i = 0; i < data.NumItems; i++)
        {
            DataModel.Weights[i] += saw;
        }
        // Create the linear solver with the SCIP backend.
        Solver solver = Solver.CreateSolver("SCIP");
        if (solver is null)
        {
            return;
        }
        //Create the variables
        Variable[,] x = new Variable[data.NumItems, data.NumBins];
        for (int i = 0; i < data.NumItems; i++)
        {
            for (int j = 0; j < data.NumBins; j++)
            {
                x[i, j] = solver.MakeIntVar(0, 1, $"x_{i}_{j}");
            }
        }
        Variable[] y = new Variable[data.NumBins];
        for (int j = 0; j < data.NumBins; j++)
        {
            y[j] = solver.MakeIntVar(0, 1, $"y_{j}");
        }
        // Define the constraints
        for (int i = 0; i < data.NumItems; ++i)
        {
            Constraint constraint = solver.MakeConstraint(1, 1, "");
            for (int j = 0; j < data.NumBins; ++j)
            {
                constraint.SetCoefficient(x[i, j], 1);
            }
        }

        for (int j = 0; j < data.NumBins; ++j)
        {
            Constraint constraint = solver.MakeConstraint(0, Double.PositiveInfinity, "");
            constraint.SetCoefficient(y[j], data.BinCapacity);
            for (int i = 0; i < data.NumItems; ++i)
            {
                constraint.SetCoefficient(x[i, j], -DataModel.Weights[i]);
            }
        }
        // Define the objective
        Objective objective = solver.Objective();
        for (int j = 0; j < data.NumBins; ++j)
        {
            objective.SetCoefficient(y[j], 1);
        }
        objective.SetMinimization();
        //Call the solver and print the solution
        Solver.ResultStatus resultStatus = solver.Solve();
        // Check that the problem has an optimal solution.
        if (resultStatus != Solver.ResultStatus.OPTIMAL)
        {
            Console.WriteLine("The problem does not have an optimal solution!");
            return;
        }
        Console.WriteLine($"Number of bins used: {solver.Objective().Value()}");
        double TotalWeight = 0.0;
        for (int j = 0; j < data.NumBins; ++j)
        {
            double BinWeight = 0.0;
            if (y[j].SolutionValue() == 1)
            {
                Console.WriteLine($"Bin {j}");
                for (int i = 0; i < data.NumItems; ++i)
                {
                    if (x[i, j].SolutionValue() == 1)
                    {
                        Console.WriteLine($"Item {i} weight: {DataModel.Weights[i]}");
                        BinWeight += DataModel.Weights[i];
                    }
                }
                Console.WriteLine($"Packed bin weight: {BinWeight}");
                TotalWeight += BinWeight;
            }
        }
        Console.WriteLine($"Total packed weight: {TotalWeight}");
    }
}

Activity

  1. lperron commented on Feb 3, 2025

    @lperron
    Collaborator

    What happens if you change the solver ?

  2. self-assigned this
    on Feb 3, 2025
  3. added this to the v10.0 milestone on Feb 3, 2025
  4. busezgi commented on Feb 3, 2025

    @busezgi
    Author

    What happens if you change the solver ?

    I hadn't changed until when you asked. I tryed "CP-SAT" solver, too. And I got the same stucking issue.
    When I set timeLimit as solver.SetTimeLimit(25000); I got the message "The problem does not have an optimal solution!"

  5. locked and limited conversation to collaborators on Feb 3, 2025
  6. converted this issue into a discussion #4530 on Feb 3, 2025
  7. modified the milestones: v10.0, v9.12 on Feb 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions