这个程序使用了大量内存,因为它有一个巨大的向量,我怎么能阻止它这样做呢?

时间:2017-05-10 00:36:54

标签: c++ visual-studio vector

我正在浏览r / dailyprogrammer,我遇到了一个我认为可以搞清楚的挑战。

我不打算详细介绍,但其中的要点是每周都有植物生产1个水果,每周生产的水果量增加1个。种植这些水果以种植更多植物。该程序一直运行,直到产生足够的水果,以便1个人在群体中获得至少1个水果,其大小由用户决定。

这里的重点是用于保存植物的载体导致大量滞后并使程序运行时间长。这是整个事情,注释为更容易理解:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

void funnyPlant() {

    int startPlants, //initial plants (determined by user)
        people,      //population (determined by user)
        fruits = 0,  //fruits that the plants produce weekly
        week;        //integer representing time passed

    cout << "Enter population: ";
    cin >> people;
    cout << "Enter initial plant quanity: ";
    cin >> startPlants;
    vector<int> plant(startPlants); //vector is created with each element representing
                                    //1 plant, the value of which representing the amount
                                    //of fruit it produces in a given week

    cout << endl << "Processing, please wait..." << endl;

    for (week = 0; fruits < people; ++week) {
        fruits = 0; //fruits is reset because they are all planted immediately
        for (int i = 0; i < plant.size(); ++i) {

            fruits += plant[i]; //total fruits from each plant are tallied, to determine
                                //if there is enough for the given population

            ++plant[i]; //plant's fruit bearing capacity is increased by 1
        }
        for (int i = 0; i < fruits; ++i)
            plant.push_back(1); //each fruit is planted, increasing the size of the vector
    }

    cout << week << " weeks required for sustainability" << endl;
    cout << "( " << plant.size() << " plants producing " << fruits << " fruits)";
    cout << endl << endl;
}

int main() {

    funnyPlant(); //function is executed
    system("pause");
    return 0;
}

现在,问题在于我使用矢量来表示植物的数量。

plant.push_back(1);

较高的人口需要更多的时间,这导致产生的水果量达到天文数量,这反过来导致向量扩展到大规模,占用了大量的记忆。

有没有解决方法,或者我可以简单地不使用矢量?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

我不喜欢完整解决方案的演示,但我觉得我必须这样做,因为大多数建议远非最佳。

[请注意:没有数学环境,所以看起来有点难看。]

您有以下信息:

  • 一开始有p_0种植物。这些植物每个都会生产一种水果(第一周)。
  • (开头没有结果。)
  • 每周收获所有植物,并将f_w收获的水果种植为新植物。这些植物将分别生产一种水果(第一周)。
  • 所有p_w已经存在的植物都将通过一种水果增加水果产量。
  • P人需要喂食,这意味着您希望种植至少P种植物。

简而言之,这是

startvalues: p_0, f_0=p_0
recursive relation: w -> w+1
    p_w+1 = p_w + f_w        // the following week every harvested fruit of this week will be planted
    f_w+1 = f_w + p_w+1      // the following week the production will increase according to the number of total plants after planting
          = f_w + p_w + f_w  // that is: every already existing plant will produce one more fruit and every new planted one will start producing one fruit

鉴于这些关系,人们可以很容易地实现一个只有三个变量的算法(第三个es w,你可能想知道它到达f_w >= P后)。这意味着:只需要O(1)内存!运行时为O(weeks)。由于水果产量增长非常快 - 超过指数 - 这意味着它的人数不是线性的,这似乎是一个好结果(并且似乎是你能得到的最好的)。

警告:以下只是一个尝试。我找不到比上面更好的解决方案。

让我们进一步尝试找到一个运行时更好的解决方案。 再看看递归关系。您可能会注意到它是一个简单的线性依赖关系,您可以通过矩阵向量乘法v_n+1 = A * v_n来表达:

/ p_w+1 \     / p_w +   f_w \   / 1  1 \ / p_w \
\ f_w+1 /  =  \ p_w + 2*f_w / = \ 1  2 / \ f_w /

现在我们可以直接用wp_0f_0)来表示一周=p_0的植物和水果生产总数的值:

/ p_w \     / 1  1 \^w / p_0 \
\ f_w /  =  \ 1  2 /   \ p_0 /

请记住:我们想知道最小w f_w >= P

问题是这个多矩阵产品仍然是O(weeks)。但幸运的是,矩阵是可对角化的。 ( - &gt; Wikipedia: Diagonalizable matrixA = S*D*S^-1,如果懒惰使用WolframAlpha来计算对角线化) 所以下面的等式成立:

/ 1  1 \     / (-1-sqrt(5))/2  (-1+sqrt(5))/2 \   / (3-sqrt(5))/2        0       \   / -1/sqrt(5)  (5-sqrt(5))/10 \
\ 1  2 /  =  \       1                1       /   \       0        (3+sqrt(5))/2 /   \  1/sqrt(5)  (5+sqrt(5))/10 /

现在我们可以将重写A^w重写为(S * D * S^-1)^w,这与S * D^w * S^-1相同。

所以我们得到:

/ p_w \                        / p_0 \
\ f_w /  =  S * D^w * S^-1  *  \ p_0 /

由于我们只想检查f_w,我们只需要等式

f_w = (cge^w + dif^w + che^w + djf^w) * p_0

其中常量cg,...是矩阵SS^-1D的矩阵条目:

      / a  b \          / e  0 \             / g  h \
S  =  \ c  d /  , D  =  \ 0  f /  , S^-1  =  \ i  j /

[注意:f不是f_wf^w也不是f^w。很抱歉字母f的双重用法。]

现在重新排序f_w并使用c=d=1

f_w = c(g+h)p_0 * e^w + d(i+j)p_0 * f^w
    = (g+h)p_0 * e^w + (i+j)p_0 * f^w

由于f_w应大于或等于P(人数),我们现在会搜索包含的w

        P = (g+h)p_0 * e^w + (i+j)p_0 * f^w
<=> P/p_0 = (g+h) * e^w + (i+j) * f^w

我们的新问题是g+h != i+j。但我们可以用一招。将等式重写为

P/p_0 = (g+h) * e * e^(w-1) + (i+j) * f * f^(w-1)

与关系

(g+h) * e = - 1 / sqrt(5)
(i+j) * f =   1 / sqrt(5)

我们得到了

P/p_0 *sqrt(5) = - e^(w-1) + f^(w-1)

嗯......我没有再进一步了。很容易解决这个等式或下面的等式(相当于一些小的约束) - 或证明上面提出的递归解决方案已经是最优的。

a = x + x^c [need to be solved for x. a and c are some known constants derived from the above ones.]

答案 1 :(得分:-1)

不是将所有内容都保存在向量中,而是应该计算生成 i 的植物数量,所以假设你有向量Cnt,在第一步你有Cnt [0] = startPlants,接下来的步骤你&#34;转移&#34; ,这是复制Cnt [i]到Cnt [i + 1],减少 i (这意味着生成我的所有东西)将在下一步产生i + 1)。对于Cnt [1],你在&#34; shift&#34; 之前加上Cnt [i] * i的总和。