Мне нужно что-то вроде этого: Алгоритм выбора игрока с максимальным количеством очков, но с заданной стоимостью
Я понимаю концепцию рюкзака и уже создал алгоритм, который дает мне оптимальное решение с использованием системы координат 0/1. Проблема в том, что я не понимаю, как реализовать ограничения, и под ограничениями я имею в виду только Х игроков для каждой позиции. Я не совсем понимаю ответ, данный amit в ссылке выше. Если бы вы могли дать мне немного просветления, это было бы здорово.
Заранее спасибо и извините за мой английский.
РЕДАКТИРОВАТЬ: Извините за отсутствие информации. Это мой первый вопрос 🙂
Вот что я сделал до сих пор.
$all_players = array();
foreach ($arr_players as $value) {
$all_players[] = array( "name" => $value['name'],
"position" => $value['position'],
"salary" => $value['salary'],
"score" => $value['score']
);
} // array sorted by salary$total_players = count($all_players);
$salary_cap = 601;
// using the knapsack 0/1 grid method
for ($x = 0; $x < $total_players; $x++) {
for ($y = 1; $y < $salary_cap; $y++) {
if ($x == 0) {
$score_arr[$x][$y] = 0;
$keep_arr[$x][$y] = 0;
} else {
if ($all_players[$x]['salary'] <= $y) {
$arr_pos = $x - 1;
$salary_left = $y - $all_players[$x]['salary'];
if ($all_players[$x]['salary'] == $y) {
$score_pres = $all_players[$x]['score'];
} else {
$score_pres = $all_players[$x]['score'] + $score_arr[$arr_pos][$salary_left];
}
$score_prev = $score_arr[$arr_pos][$y];
if ($score_pres > $score_prev) {
$score_arr[$x][$y] = $score_pres;
$keep_arr[$x][$y] = 1;
} else {
$score_arr[$x][$y] = $score_prev;
$keep_arr[$x][$y] = 0;
}
} else {
$score_arr[$x][$y] = 0;
$keep_arr[$x][$y] = 0;
}
}
}
}$total_players = $total_players - 1;
$salary_left = 600;
$best_lineup = array();
//
for ($x = $total_players; $x > -1; $x--) {
if ($keep_arr[$x][$salary_left] == 1) {
$best_lineup[] = $all_players[$x]['name'];
$salary_left = $salary_left - $all_players[$x]['salary'];
}
}
/////////////////////////////////////////////////
/*
The output:
Array
(
[0] => Ramon Sessions // PG
[1] => Omri Casspi // SF
[2] => D.J. Augustin // PG
[3] => Steven Adams // C
[4] => Zach LaVine // PG
[5] => Kris Humphries // PF
[6] => Isaiah Canaan // PG
[7] => Corey Brewer // SF
[8] => Rodney Stuckey // SG
[9] => O.J. Mayo // SG
[10] => Greg Monroe // PF
[11] => DeMarcus Cousins // C
)
*/
Теперь мне нужно ограничить этот массив, чтобы иметь только 2 игрока с каждой позиции (PG, SG, SF, PF) и 1 из позиции C для лучшего состава из 9 игроков.
// team position with wanted amount of players
$team = array("PG" => 2, "SG" => 2, "SF" => 2, "PF" => 2, "C" => 1);
$x = $total_players;
$salary_left = 600;
$best_lineup = array();
//
while (--$x > -1) {
if ($keep_arr[$x][$salary_left] == 1) {
$pos = $all_players[$x]['position'];
if ($team[$pos] > 0) {
// we need another player for that pos
$team[$pos]--; // same as $team[$pos] = $team[$pos] -1;
$best_lineup[] = $all_players[$x]['name'];
$salary_left = $salary_left - $all_players[$x]['salary'];
}
}
}
Других решений пока нет …