У меня есть массив с рецептами из 3 категорий: завтрак, обед и ужин. У каждой из этих категорий есть 10 уникальных рецептов.
$recipes = [
'breakfast' => [
0 => [
'title' => 'eggless waffles',
'calorie' => 210,
],
1 => [
'title' => 'blueberry oatmeal',
'calorie' => 161,
],
...
],
'lunch' => [9],
'dinner' => [9]
];
Я бы хотел отсортировать и создать комбинацию из 3 рецептов на каждый день
$days = array_fill(0, 6, [1 => [], 2 => [], 3 => []]);
Каждый рецепт имеет калорийность ie сумма, и каждый последний день должен иметь комбинацию (состоит из 1 завтрака, 1 обеда и 1 ужина) с рецептами, которые были заказаны в зависимости от того, какой комбо из 3 рецептов попадал ближе всего к 500
Например, если день 1 комбинированные рецепты (завтрак, обед и ужин) калорийность ie составила 660, а день 2 был 400. Вполне возможно, что переключение завтрака со дня 2 на день 1 может привести к тому, что оба из них попадут ближе к 500, однако возможно, что день переключения 3 завтрака к 1-му дню и 2-го к 3-му дню также могут приблизить все 3 к 500.
Таким образом, в 1, 2, 3, 4, 5, 6 и 7 дни должно быть 3 рецепта ( завтрак, обед и ужин)
$final = [
0 => [
'breakfast' => [...],
'lunch' => [...],
'dinner' => [...],
],
1 => [
'breakfast' => [...],
'lunch' => [...],
'dinner' => [...],
],
2 => [
'breakfast' => [...],
'lunch' => [...],
'dinner' => [...],
],
...
];
Прошло много дней с тех пор, как я зашел в тупик, и я не могу понять, как go сортировать эти массивы в комбинации по 3 на каждый день. (Я знаю, что я не предоставляю много кода для go off)
Edit 1: Это то, что я получил до сих пор:
class Combinations {
private $days;
public function __construct(){
$this->days = array_fill(1, 7, [1 => [], 2 => [], 3 => []]);
}
public function create(){
$median = 600;
foreach($this->days as $day => $categories){
while($this->dayIsIncomplete($day)){
$recipes = [];
foreach($categories as $category => $value){
$recipes[$category] = $this->getRandomRecipe($category);
}
// add random meals to first day
if($day === 1){
$this->days[$day] = $recipes;
continue;
}
foreach($recipes as $category => $recipe){
foreach($this->days as $dayKey => $mealsArray){
$originalMacros = $this->totalMacros($mealsArray);
// remove $recipe category from mealsArray, and merge it ($recipe)
$filteredMacros = $this->totalMacros(array_merge([$recipe], array_filter($mealsArray, function($key) use($category){
return $key !== $category;
}, ARRAY_FILTER_USE_KEY)));
// if original is not closer to median
if(($originalMacros - $median) * ($originalMacros - $median) < ($filteredMacros - $median) * ($filteredMacros - $median)){
// flip current recipes
// switch D2B ($recipe) with D1B
}
}
}
}
}
}
public function getRandomRecipe(int $category){
$recipes = []
if($category === 1){
$recipes[] = ['id' => 1, 'calorie' => 310];
$recipes[] = ['id' => 2, 'calorie' => 360];
$recipes[] = ['id' => 3, 'calorie' => 450];
$recipes[] = ['id' => 4, 'calorie' => 330];
$recipes[] = ['id' => 5, 'calorie' => 220];
$recipes[] = ['id' => 6, 'calorie' => 390];
$recipes[] = ['id' => 7, 'calorie' => 400];
$recipes[] = ['id' => 8, 'calorie' => 320];
$recipes[] = ['id' => 9, 'calorie' => 460];
}
if($category === 2){
$recipes[] = ['id' => 10, 'calorie' => 420];
$recipes[] = ['id' => 11, 'calorie' => 360];
$recipes[] = ['id' => 12, 'calorie' => 450];
$recipes[] = ['id' => 13, 'calorie' => 310];
$recipes[] = ['id' => 14, 'calorie' => 320];
$recipes[] = ['id' => 15, 'calorie' => 490];
$recipes[] = ['id' => 16, 'calorie' => 440];
$recipes[] = ['id' => 17, 'calorie' => 520];
$recipes[] = ['id' => 18, 'calorie' => 560];
}
if($category === 3){
$recipes[] = ['id' => 19, 'calorie' => 510];
$recipes[] = ['id' => 20, 'calorie' => 660];
$recipes[] = ['id' => 21, 'calorie' => 750];
$recipes[] = ['id' => 22, 'calorie' => 610];
$recipes[] = ['id' => 23, 'calorie' => 580];
$recipes[] = ['id' => 24, 'calorie' => 690];
$recipes[] = ['id' => 25, 'calorie' => 710];
$recipes[] = ['id' => 26, 'calorie' => 620];
$recipes[] = ['id' => 27, 'calorie' => 730];
}
return $recipes[array_rand($recipes)];
}
public function dayIsIncomplete($day){
return !empty($this->days[$day][1]) && !empty($this->days[$day][2]) && !empty($this->days[$day][3]);
}
public function totalMacros($array){
$total = 0;
foreach ($array as $key => $value) {
$total += $value['calorie'];
}
return $total / 2;
}
}
Edit 2:
Я пытаюсь выяснить, какой алгоритм лучше всего подходит для решения этой проблемы. Я думаю, что мне может понадобиться использовать алгоритм двойного соответствия (максимум).
Редактировать 3:
Спасибо всем, что нашли время помочь, я не забыл об ответах. Мне пришлось отложить это на некоторое время, однако достаточно скоро я доберусь до него, и принятый ответ получит мои оставшиеся 300 щедрых.