Skip to content

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

@busezgi

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}");
    }
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions