#php #algorithm #math #search
#php #алгоритм #математика #Поиск
Вопрос:
У меня есть несколько продуктов, у всех которых есть размеры, и мне нужно найти самую дешевую конфигурацию, которая соответствует минимально необходимому размеру.
Например, Джону нужно минимум 10 литров хранилища — это может быть больше, но не меньше.
Есть варианты 2L, 3L, 5L, 8L и 10L (но это может измениться).
В качестве примера, может быть дешевле получить:
- контейнер объемом 1×10 л ИЛИ
- контейнеры объемом 2×5 л Или
- 1x2L, 1x3L и 1x5L ИЛИ
- 4x3L (этот занимает более 10 литров, но все еще возможно, что он будет дешевле)
До сих пор я пытался выполнять цикл снова и снова до 4 раз (потому что обычно максимальное требование будет составлять 40 литров), но в некоторых случаях у меня заканчивается память, и это не кажется самым эффективным способом сделать это.
// Size is in mL
$available_containers = [
[
'id' => 22700,
'price' => 1190,
'size' => 2000,
],
[
'id' => 22701,
'price' => 1245,
'size' => 3000,
],
[
'id' => 22702,
'price' => 1415,
'size' => 4000,
],
[
'id' => 22715,
'price' => 12300,
'size' => 5000,
],
[
'id' => 22706,
'price' => 1740,
'size' => 5000,
],
[
'id' => 22703,
'price' => 1510,
'size' => 5000,
],
[
'id' => 22707,
'price' => 1790,
'size' => 6000,
],
[
'id' => 22704,
'price' => 1770,
'size' => 6000,
],
[
'id' => 22708,
'price' => 2215,
'size' => 7000,
],
[
'id' => 22705,
'price' => 2195,
'size' => 8200,
],
[
'id' => 22709,
'price' => 2660,
'size' => 8200,
],
[
'id' => 22710,
'price' => 2799,
'size' => 10000,
],
[
'id' => 22711,
'price' => 2910,
'size' => 12500,
],
[
'id' => 22712,
'price' => 3260,
'size' => 15000,
],
[
'id' => 22713,
'price' => 4130,
'size' => 20000,
],
[
'id' => 22714,
'price' => 3770,
'size' => 27000,
]
];
$required_size = 8; // Can change.
$container_install = 5;
foreach ( $available_containers as $v ){
foreach ( $available_containers as $v2 ){
foreach ($available_containers as $v3 ) {
foreach ( $available_containers as $v4 ){
$all_configs = [
[
'size' => $v['size'],
'configuration' => [ $v['size'] ],
'price' => $v['price'],
],
[
'size' => $v['size'] $v2['size'],
'configuration' => [ $v['size'], $v2['size'] ],
'price' => $v['price'] $v2['price'] $container_install,
],
[
'size' => $v['size'] $v2['size'] $v3['size'],
'configuration' => [ $v['size'], $v2['size'], $v3['size'] ],
'price' => $v['price'] $v2['price'] $v3['price'] $container_install $container_install,
],
[
'size' => $v['size'] $v2['size'] $v3['size'] $v4['size'],
'configuration' => [ $v['size'], $v2['size'], $v3['size'], $v4['size'] ],
'price' => $v['price'] $v2['price'] $v3['price'] $v4['price'] $container_install $container_install $container_install,
],
];
foreach ( $all_configs as $c ){
if ( $c['size'] >= $required_size ){
$configuration[] = array(
'configuration' => $c['configuration'],
'size' => $c['size'],
'price' => $c['price'],
);
}
}
}
}
}
}
// Sort by price.
$sorted_configs = array_sort($configuration, 'price', SORT_ASC); // This function simply sorts all permutations by price
Комментарии:
1. n x n x n n x n не является хорошей сложностью. вы можете попробовать эту рекурсивную функцию docstore.mik.ua/orelly/webprog/pcook/ch04_26.htm
2. Что вам нужно сделать, это выполнить цикл один раз, возможно, с циклом while, затем использовать деление, чтобы получить количество раз, которое оно входит в каждый (в порядке от наибольшего к наименьшему), Вычесть это значение и сделать это снова. Каждый раз уменьшая исходное значение.
3. Похоже, это скорее вопрос для codereview.stackexchange.com
4. Спасибо @JosuaMarcelChrisano — я посмотрю.
5. @ArtisticPhoenix — Я не математический гений — просто программист, ха-ха. Можете ли вы пояснить на примере?
Ответ №1:
Ну, есть некоторые моменты, которые могут сделать эти циклы легкими. Эта проблема должна быть решена с помощью подхода «разделяй и властвуй».
- Создайте подмассив, потому что вам не нужен весь массив, только новый подмассив от 1L до 10L.
- Вложенный массив должен быть отсортирован по цене, от наименьшей к высоте.
- Тогда и только тогда, когда самая низкая цена, которая представлена в первом индексе, может быть куплена только один раз,
break
цикл. - В противном случае у вас должен быть список, который принимает выходные данные, когда вы уже выполняете цикл.