拟合货架问题[贪婪算法]

112 阅读3分钟

在这篇文章中,我们将了解什么是装修货架问题,并将看到解决这一问题的贪婪方法算法。

装架子问题是什么意思?

这个问题是这样说的:给定一个长度为W的墙和两个长度为mn的架子,我们的任务是用长度为mn的架子来装配长度为W的墙,使空出的空间(不能被架子填满)最小化,如果可能的话,有更多长架子的方案将被优先考虑,因为长架子是比较便宜的,但在我们冒险使成本最小化时,成本仍然是次要的,我们应该更担心如何使空位最小化(如果可能,它应该为零)。

例如*:*假设有一堵长为24的墙,有两个长为5和3的架子,我们需要尽量减少墙上的空位,如果可能的话,我们也应该尝试尽量减少成本(但这是次要的)。

通过智能猜测(因为我们还没有任何算法),我们可以看到,要么我们可以用8个长度为3的架子来填充,要么我们可以用3个长度为5的架子和3个长度为3的架子,这样,总共有6个架子。
因此,根据这个问题的陈述,我们的解决方案是用3个长度为5的架子和3个长度为3的架子,因为这将使空位最小化(没有空间),也将使成本最小化,因为我们使用的是更多的长架子,比较便宜。

Fitting_shelves_example

装配货架问题的蛮力方法

一种解决装配货架问题的方法是,我们用两个变量组成一个方程,然后尝试各种数值的组合,直到我们得到我们喜欢的解决方案。

例如:假设我们有一堵长为31的墙,有两个分别为6和3的架子,我们需要为这堵墙找到合适的架子问题的解决方案。
使用蛮力法:--

让长度为6的架子的数量为x,长度为3的架子的数量为y,那么,对于最佳解决方案,架子的总长度为6x*+3y*,我们必须尝试x和y值的每个组合,然后找到每个组合的空位,找到我们的最佳解决方案。
输入的x和y的值只能是整数,范围是0<=x<=(int)31/6;0<=y<=(int)31/3,这与
0<=x<=5;0<=y<=10
相同

因此,我们必须尝试50种组合才能得到这个问题的最优解。
或者说,要尝试的组合总数是 O((W^2)/(mn))
因此,我们需要开发一种耗费资源较少的算法来解决同样的问题。

适应货架问题的贪婪算法

在贪婪算法中,我们要么尝试最小化,要么尝试在每一个阶段最大化某些数量。在这里,我们将尝试在每个阶段尽量减少墙上的空位,并将其存储在一个计数器变量中,该变量将用于跟踪最小的空位以及相应的长度为mn的货架数量的计数器变量。然后,我们将根据下面提到的贪婪算法步骤进行迭代,以获得所需的解决方案。

拟合货架问题的贪婪算法步骤如下:- 1.

1.在贪婪算法中,问题的约束条件是大货架的成本低于小货架的成本,我们从0开始,增加长货架的数量,直到不能再装更多的长货架。
2.对于每个迭代,我们找到该迭代中的空位,并与该迭代前的最小情感空间进行比较,如果该阶段的值小于该阶段前的值,我们更新最小空位
。如果在两种情况下最小空位是相同的,那么我们将更新最小空位,只有当它有更多的大货架数量时,迭代结束时的最小空位值将是我们的解决方案,同时还有相应的大长度货架和小长度货架的数量。

实施:-

#include<iostream>
using namespace std;
 
void Fitting_shelf(int wall_length, int smaller, int larger)
{
    // Output variables
    int smaller_used = 0, larger_used = 0, min_empty = wall_length;
    // p and q are no of shelves of smaller length  and larger length respectively.
    // remaining_length is the length which can't be filled in this iteration.
    int p;
    int q = -1; //For sake of programming simplicity, it has been declared as -1.
    int remaining_length;
    while (wall_length >= larger) 
    {
        // place one more shelf of larger length 
        q += 1;
        if(q>0)
        wall_length = wall_length - larger;
        //As many shelves of smaller length are to be placed till no more smaller length ones can be placed.
        p = wall_length / smaller;
        remaining_length = wall_length % smaller;
 
        //Output variables are to be updated if remaining_length is lesser than previous least empty space.
        if (remaining_length <= min_empty) 
        {
            smaller_used = p;
            larger_used = q;
            min_empty = remaining_length;
        }
    }
    cout<<"Number of smaller length shelf used is"<<smaller_used<<endl;
    cout<<"Number of larger length shelf used is"<<larger_used<<endl;
    cout<<"Least empty space or the corresponding number of shelves is"<<min_empty<<endl;
}

int main()
{
    int wall,smaller,larger;
    cout<<"Enter the length of the wall";
    cin>>wall;
    cout<<"Enter the length of the smaller shelf";
    cin>>smaller;
    cout<<"Enter the length of the larger shelf";
    cin>>larger;
    Fitting_shelf(wall,smaller,larger);
    return 0;
}

代码的复杂度:-

空间复杂度是恒定的,因为分配的空间总量是恒定的,并不取决于输入。

因此,空间复杂度为 O(1)
由于循环运行了大货架的Wall_length/Length次数,因此,这段代码的时间复杂度为O(Wall_length/Length_of_largershelf)

问题

如果墙的长度是34,架子的长度是5和8,使用拟合架子的算法找出最小的空位。

0

1

2

3

3个长度为8的架子和2个长度为5的架子将产生0的空位。

通过OpenGenus的这篇文章,你一定对装配货架的问题有了完整的认识。