GoogleOR-Tools(六)装箱问题BinPacking

更新时间:2023-08-09 03:53:10 阅读: 评论:0

GoogleOR-Tools (六)装箱问题BinPacking
本⽂参考Google OR-Tools介绍OR-Tools的使⽤⽅法。
的描述是要将⼀组给定尺⼨的物品放置到具有固定容量的容器中,⼀般情况下由于容器有容量限制,不可能放⼊所有物品,那么装箱问题的⽬标是要找到限定约束下使得总价值最⼤或总花费最⼩的装箱⽅法。根据我们具体的⽬标情况,装箱问题⼜可分为两类:
背包问题(Knapsack problem),容器数量是固定的,每个容器有⾃⼰的最⼤容量,⽽需要分配的物件有各⾃的价值,我们的⽬标是让装⼊容器的物体的总价值最⼤,并不要求所有物体都装⼊;
Bin-packing问题,容器容量是相同的,但是数量不固定,我们的⽬标是⽤最少的容器来存放所有的物件。
OR-Tools针对典型的单背包问题提供了专⽤的接⼝,对于更⼀般的多背包问题和-packing问题则需要使⽤通⽤的整数规划接⼝来计算。这篇⽂章⾥我就参考官⽅教程演⽰⽤OR-Tools对单背包问题、多背包问题和Bin-Packing问题进⾏建模。
1 单背包问题
如果背包问题中只有⼀个背包,那么就是单背包问题,⼀般也成为0-1背包问题,因为它可以⽤下⾯的⽅程式来描述问题:⽤0-1变量表⽰第个物件是否放⼊背包,表⽰物件的价值,则表⽰物件的重量,则是背包的最⼤承重,那么整个问题可表⽰为:maximize subject to i=1∑n vi x i i=1∑n wi x i ≤W xi ∈{0,1}
当然实际⽣活中可能限制背包存放物体数量的不仅是重量,还有体积等属性,因此上⾯的定义更严格的来说应该是单维单背包问题,如果有多维限定,那么在每⼀维存放物体的总量都不能超过背包的限定值。
我们新建⼀个 Core控制台应⽤,⾃定义⼀个单背包问题的数据:
holmes
OR-Tools提供了⼀个KnapsackSolver来专门处理单背包问题,我们定义这个KnapsackSolver对象,并且指定使⽤分⽀界定算法然后就可以初始化KnapsackSolver对象并求解了
Solve()⽅法的返回值就是算法的最终⽬标值,⽽如果要知道那些物件被放置,则需要调⽤BestSolutionContains()⽅法查看。
x i i v i i w i W    //values[i], the value of item i            long [] values = { 360, 83, 59, 130, 431, 67, 230, 52, 93,                      125, 670, 892, 600, 38, 48, 147, 78, 256,                      63, 17, 120, 164, 432, 35,
92, 110, 22,                      42, 50, 323, 514, 28, 87, 73, 78, 15,                      26, 78, 210, 36, 85, 189, 274, 43, 33,                      10, 19, 389, 276, 312 };            //weights[i,j], the weight of weights[i][j]            long [,] weights = { { 7, 0, 30, 22, 80, 94, 11, 81, 70,                          64, 59, 18, 0, 36, 3, 8, 15, 42,                          9, 0, 42, 47, 52, 32, 26, 48, 55,                          6, 29, 84, 2, 4, 18, 56, 7, 29,                          93, 44, 71, 3, 86, 66, 31, 65, 0,                          79, 20, 65, 52, 13 } };            long [] capacities = { 850 };
1
2
3
4
5
bcs6
7
8
until you9
10
克格勃特工11
12
13
14
15
16
17KnapsackSolver solver = new  KnapsackSolver (    KnapsackSolver .SolverType .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER ,    "KnapsackExample");
1
2
3            solver .Init (values , weights , capacities );            long  computedValue = solver .Solve ();
1
2
完整的程序            Console .WriteLine ("Optimal Value = " + computedValue );            string  lectItems = $"Selected item indexs : ";            for  (int  i = 0; i < values .Length ; i ++)            {                if  (solver .BestSolutionContains (i ))                {                    lectItems += $"{i}({values[i]}), ";                }            }            Console .WriteLine (lectItems );
1
2prado
3
4
htl
5
6
7
8
9
10using  System ;using  Google .OrTools .Algorithms ;namespace  SingleKnapsackProblem {    class  Program    {        static  void  Main (string [] args )        {            //Create a knapsack solver, u Branch And Bound algorithm            KnapsackSolver solver = new  KnapsackSolver (                KnapsackSolver .SolverType .KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER ,                "KnapsackExample");            //values[i], the value of item i            long [] values = { 360, 83, 59, 130, 431, 67, 230, 52, 93,                      125, 670, 892, 600, 38, 48, 147, 78, 256,                      63, 17, 120, 164, 432, 35, 92, 110, 22,                      42, 50, 323, 514, 28, 87, 73, 78, 15,                      26, 78, 210, 36, 85, 189, 274, 43, 33,                      10, 19, 389, 276, 312 };            //weights[i,j], the weight of weights[i][j]            long [,] weights = { { 7, 0, 30, 22, 80, 94, 11, 81, 70,                          64,
59, 18, 0, 36, 3, 8, 15, 42,                          9, 0, 42, 47, 52, 32, 26, 48, 55,                          6, 29, 84, 2, 4, 18, 56, 7, 29,                          93, 44, 71, 3, 86, 66, 31, 65, 0,                          79, 20, 65, 52, 13 } };            long [] capacities = { 850 };            solver .Init (values , weights , capacities );            long  computedValue = solver .Solve ();            Console .WriteLine ("Optimal Value = " + computedValue );            string  lectItems = $"Selected item indexs : ";            for  (int  i = 0; i < values .Length ; i ++)            {                if  (solver .BestSolutionContains (i ))                {                    lectItems += $"{i}({values[i]}), ";                }            }            Console .WriteLine (lectItems );        }    }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
brilliant22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43孤儿院英文
44
45
46
47
2 多背包问题
把单个背包扩展到多个背包,就是多背包问题,对于多背包问题,我们可以采⽤下⾯的定义⽅式:
给出个物件和个背包(),并且按如下定义(仍然只是单维):
vj :物件j的价值wj :物件j的重量ci :第i个背包的容量
要让每个背包不超过容量限制的情况下最⼤化放置的物件的价值总量,即:
其中是0-1变量,表⽰物件是否分配到背包中。
对于多背包问题,OR-Tools没有提供直接的接⼝,不过从它的建模⽅程来看,这是⼀很典型的整数规划问题,因此我们可以例⽤OR-Tools 的整数规划接⼝来建模和计算。
我们先⾃定义⼀个问题的数据源,假设有15个物件和5个背包,每个背包的最⼤承重都是100
新建⼀个整数规划求解对象,这⾥指定内部连接CBC求解器
n m m ≤n maximize
subject  to v x i =1∑j =1∑j ij w x ≤c ,i ∈M ={1,...m }j =1∑
n j ij i x ≤1,j ∈N ={1,...n }
i =1∑m ij x ∈{0,1}
ij x ij j i        class  DataModel        {            public  double [] Weights =              {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36};            public  double [] Values =              {10, 30, 25, 50, 35, 30, 1
5, 40, 30, 35, 45, 10, 20, 30, 25};            public  double [] BinCapacities = { 100, 100, 100, 100, 100 };            private  int  numItems ;            public  int  NumItems            {                get                {                    numItems = Weights .Length ;                    return  numItems ;                }                t                {                    numItems = value ;                }            }            public  int  NumBins = 5;        }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22            // Create the linear solver with the CBC backend.            Solver solver = Solver .CreateSolver ("SimpleMipProgram", "CBC_MIXED_INTEGER_PROGRAMMING");
1
2
然后定义求解变量,即个0-1变量
接着是两个,约束⼀是对⼀个物件,最多只会被分配在⼀个背包;约束⼆是每个背包内的物件的重量和不会超过限制
最后就可以定义⽬标并求解了
完整的代码
i ×j            // Create variables, x[i][j]=1 means item i is packed in bin j            Variable [,] x = new  Vari
able [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, String .Format ("x_{0}_{1}", i , j ));                }            }
1
2
3
4
5
6
7
8
9            //Item i can't be packed in more than one bins            for  (int  i = 0; i < data .NumItems ; ++i )
            {                LinearExpr sum =new  LinearExpr ();                for  (int  j = 0; j < data .NumBins ; ++j )                {                    sum += x [i ,j ];                }                solver .Add (sum <= 1.0);            }            //The amount packed in each bin cannot exceed its capacity            for  (int  j = 0; j < data .NumBins ; ++j )            {                LinearExpr Weight =new  LinearExpr ();                for  (int  i = 0; i < data .NumItems ; ++i )                {                    Weight += data .Weights [i ] * x [i ,j ];                }                solver .Add (Weight <= data .BinCapacities [j ]);            }
英语翻译软件下载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20            //Objective            LinearExpr totalValue =new  LinearExpr ();            for  (int  i = 0; i < data .NumItems ; ++i )            {                for  (int  j = 0; j < data .NumBins ; ++j )                {                    totalValue += data .Values [i ] * x [i ,j ];                }            }            solver .Maximize (totalValue );            //Solve it            Solver .ResultStatus resultStatus = solver .Solve ();
1
2
3
4
5
6
7
8
9
10
11
12
13using  System ;using  Google .OrTools .LinearSolver ;namespace  MultipleKnapsackProblem {    class  Program    {        class  DataModelabbey
1
2
3
4
5
6
7
8
class  DataModel        {            public  double [] Weights =              {48, 30, 42, 36, 36, 48, 42, 42, 36, 24, 30, 30, 42, 36, 36};            public  double [] Values =              {10, 30, 25, 50, 35, 30, 15, 40, 30, 35, 45, 10, 20, 30, 25};            public  double [] BinCapacities = { 100, 100, 100, 100, 100 };            private  int  numItems ;            public  int  NumItems            {                get                {                    numItems = Weights .Length ;                    return  numItems ;                }                t                {                    numItems = value ;                }            }            public  int  NumBins = 5;        }        static  void  Main (string [] args )        {            DataModel data = new  DataModel ();            // Create the linear solver with the CBC backend.            Solver solver = Solver .CreateSolver ("SimpleMipProgram", "CBC_MIXED_INTEGER_PROGRAMMING");            // Create variables, x[i][j]=1 means item i is packed in bin j            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, String .Format ("x_{0}_{1}", i , j ));                }            }
            //Item i can't be packed in more than one bins            for  (int  i = 0; i < data .NumItems ; ++i )            {                LinearExpr sum =new  LinearExpr ();                for  (int  j = 0; j < data .NumBins ; ++j )                {                    sum += x [i ,j ];                }                solver .Add (sum <= 1.0);            }            //The amount packed in each bin cannot exceed its capacity            for  (int  j = 0; j < data .NumBins ; ++j )            {                LinearExpr Weight =new  LinearExpr ();                for  (int  i = 0; i < data .NumItems ; ++i )                {                    Weight += data .Weights [i ] * x [i ,j ];                }                solver .Add (Weight <= data .BinCapacities [j ]);            }                        //Objective            LinearExpr totalValue =new  LinearExpr ();            for  (int  i = 0; i < data .NumItems ; ++i )            {                for  (int  j = 0; j < data .NumBins ; ++j )                {                    totalValue += data .Values [i ] * x [i ,j ];                }8910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273

本文发布于:2023-08-09 03:53:10,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/191951.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:背包   问题   物件   算法   限制   容量   规划   容器
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图