Answer the question
In order to leave comments, you need to log in
What algorithm can be applied to the problem of placing a number in fixed containers?
Please let me know what this problem looks like and how it can be solved. php language.
The pump is assembled in sections. The pump itself contains the pump stages - this is the number N.
For example, we have N = 300 stages in the pump.
There are containers:
length, m _______ max. number of steps in the container
3.0 ________ 95
3.5 ________ 111
4.0 ________ 127
4.5 ________ 144
5.0 ________ 160
5.5 ________ 177 6.0
________
193
but it is possible and not completely (stubs are placed).
For this example, the result can be written as "4.5 + 5.0" = 9.5 meters, i.e. we scattered 300 steps in 2 containers 144 + 160 = 304, respectively, in one of the containers there will be 4 stubs.
But too many stubs are very bad, so there are no more than 20% of the maximum number in the section.
There may be more options "4.0 + 5.5" = 9.5 meters, 127 + 177 = 304 steps.
Or another such "3.0 + 3.5 + 3.5" = 10m
Accordingly, the best option is the minimum length and minimum sections.
Answer the question
In order to leave comments, you need to log in
Your problem is very similar to the knapsack problem.
Firstly, you can forget about the stubs if you require to collect exactly from N to 1.25N sections.
Those. in your example, you can collect from 300 to 400 sections.
Now your problem becomes exactly the knapsack problem, the number of sections in the container is the "length" of the thing from the knapsack problem, and the length is the "price".
And you need, as in the knapsack problem, to collect some "things", incl. the backpack is filled from 300 to 400 and the total "price" is minimal.
If there are not many containers (up to 20-25), then you can solve by exhaustive enumeration: using a recursive function, iterate over how many containers of each type you take in response. If the total number of sections is above 1.25N, then stop. At the end, when all the containers have been sorted out, if you have collected from N to 1.25N sections, then you compare the current length with the optimal answer and remember if the length is less.
A fairly quick solution is through dynamic programming. Get an array from 0 to 1.25N. It will store the minimum possible length for a set of containers with a given number of sections. Initially fill it with -1, and put 0.0 in index [0].
Now, for each container, iterate through the array from left to right, and if the current length is non-negative, then try to append the current section to the set, adding the number of sections to the index and the length to the array value. If the new index contains something worse than what you counted, overwrite this value. I don't know php, here's a C++ solution for you.
// Container - структура содержащая длину length и количество секций sections.
int maxn = n*5/4; // Округленное вниз целое число.
vector<float> length(maxn+1, -1.0);
length[0] = 0.0;
vector<container> best(maxn+1);
for (Container c: containers) {
for(int i = 0; i < maxn; ++i) {
if (length[i] < 0) continue;
int j = i + с.sections;
if (j <= maxn && (length[j] < 0 || length[j] > length[i] + c.length)) {
length[j] = length[i] + c.length;
best[j] = c;
}
}
}
int besti = -1;
float bestlen = 100000000;
for (int i = n; i <= maxn; ++i) {
if (length[i] > 0 && length[i] < bestlen) {
besti = i;
bestlen = length[i];
}
}
if (besti == -1) {
cout << "Нет решения" << endl;
} else {
cout << "Минимально возможная длина: " << length[besti] << endl;
cout << "Контейнеры:" << endl;
while (besti > 0) {
cout << best[besti].length << endl;
besti -= best[besti].sections;
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question