Алгоритм хоккейного пула

Это небольшой веселый проект, который я начал пытаться максимизировать свои шансы на победу в нашем офисном хоккейном бассейне. Я пытаюсь найти лучший способ выбрать 20 игроков, которые дадут мне больше точки в пределах максимальной зарплаты.

Например, представьте, что необработанные данные сделаны из

  1. Имя игрока
  2. Позиция (форвард, защитник, вратарь)
  3. Прогнозируемый объем точек на этот сезон
  4. Зарплата.

Теперь я хочу 20 игроков, которые дадут мне наибольший пункт в пределах X оклада. Позже, как фаза 2, я хотел бы сделать то же самое, однако в этом случае, я хочу только 12 форвардов, 6 защитников и 2 вратарей.

Теперь очевидным путем является просто пройти все возможные комбинации, однако, хотя это будет работать это не является действительным вариантом, как с 500 игроков, это будет слишком много возможной комбинации. Я мог бы добавить несколько умных фильтров, чтобы сократить 500 игроков в топ-50 форвардов, топ-30 защитников и топ-15 вратарей, но все же, это будет очень медленный процесс.

Мне интересно, есть ли другие алгоритмы, чтобы реализовать это. Это просто для удовольствия и не важный бизнес-запрос. Но если у вас есть некоторые мысли о том, как действовать, пожалуйста, дайте мне знать.

Моя первая попытка была использовать алгоритм knapsack с помощью других источников. Вроде бы работает как раз с Зарплатой как параметром. Я пытаюсь понять, как добавить параметр команды 20 игроков. Его в .Net, но должно быть легко преобразовать в Java.

Я думал сделать отдельный цикл, чтобы выяснить лучшие команды с 20 игроками, независимо от зарплаты, а затем сравнить два списка, пока я не нахожу команду, которая является самой высокой в двух списках. Не уверен.

namespace HockeyPoolCalculator
{
public class ZeroOneKnapsack
{

protected List<Item> itemList = new List<Item>();
protected int maxSalary = 0;
protected int teamSize = 0;
protected int teamSalary = 0;
protected int points = 0;
protected bool calculated = false;

public ZeroOneKnapsack() { }

public ZeroOneKnapsack(int _maxSalary)
{
setMaxSalary(_maxSalary);
}

public ZeroOneKnapsack(List<Item> _itemList)
{
setItemList(_itemList);
}

public ZeroOneKnapsack(List<Item> _itemList, int _maxSalary)
{
setItemList(_itemList);
setMaxSalary(_maxSalary);
}

// calculte the solution of 0-1 knapsack problem with dynamic method:
public virtual List<Item> calcSolution()
{
int n = itemList.Count;

setInitialStateForCalculation();
if (n > 0 && maxSalary > 0)
{
List<List<int>> playerList = new List<List<int>>();
List<int> salaryList = new List<int>();

//initialise list
playerList.Add(salaryList);
for (int j = 0; j <= maxSalary; j++)
salaryList.Add(0);
// Loop through players
for (int i = 1; i <= n; i++)
{
List<int> prev = salaryList;
playerList.Add(salaryList = new List<int>());
for (int j = 0; j <= maxSalary; j++)
{
if (j > 0)
{
int wH = itemList.ElementAt(i - 1).getSalary();
// Is the players salary more than the current calculated salary? If yes, then keep current max points, else get the highest amount between previous max points at that salary and new max points.
salaryList.Add((wH > j)?prev.ElementAt(j): Math.Max(prev.ElementAt(j),itemList.ElementAt(i - 1).getPoints() + prev.ElementAt(j - wH)));
}
else
{
salaryList.Add(0);
}
} // for (j...)
} // for (i...)
points = salaryList.ElementAt(maxSalary);

for (int i = n, j = maxSalary; i > 0 && j >= 0; i--)
{
int tempI = playerList.ElementAt(i).ElementAt(j);
int tempI_1 = playerList.ElementAt(i - 1).ElementAt(j);
if ((i == 0 && tempI > 0)||(i > 0 && tempI != tempI_1))
{
Item iH = itemList.ElementAt(i - 1);
int wH = iH.getSalary();
iH.setInKnapsack(1);
j -= wH;
teamSalary += wH;
}
} // for()
calculated = true;
} // if()
return itemList;
}

// add an item to the item list
public void add(String name, int Salary, int value)
{
if (name.Equals(""))
name = "" + (itemList.Count() + 1);
itemList.Add(new Item(name, Salary, value));
setInitialStateForCalculation();
}

// add an item to the item list
public void add(int Salary, int value)
{
add("", Salary, value); // the name will be "itemList.size() + 1"!
}

// remove an item from the item list
public void remove(String name)
{
for (int pointer = 0; pointer <= itemList.Count-1; pointer++)

{
itemList[pointer].getName().Equals("");

if (itemList.ElementAt(pointer).getName().Equals(itemList.ElementAt(pointer).getName()))
{
itemList.Remove(itemList.ElementAt(pointer));
}
}
setInitialStateForCalculation();
}

// remove all items from the item list
public void removeAllItems()
{
itemList.Clear();
setInitialStateForCalculation();
}

public int getPoints()
{
if (!calculated)
calcSolution();
return points;
}

public int getSolutionSalary() { return teamSalary; }
public bool isCalculated() { return calculated; }
public int getMaxSalary() { return maxSalary; }

public void setTeamSize(int _teamSize)
{
teamSize = _teamSize;
}

public int getTeamSize()
{
return teamSize;
}

public void setMaxSalary(int _maxSalary)
{
maxSalary = Math.Max(_maxSalary, 0);
}

public void setItemList(List<Item> _itemList) {
if (_itemList != null) {
itemList = _itemList;
foreach (Item item in _itemList) {
item.checkMembers();
}
}
}

// set the member with name "inKnapsack" by all items:
private void setInKnapsackByAll(int inKnapsack) {
foreach (Item item in itemList)
if (inKnapsack > 0)
item.setInKnapsack(1);
else
item.setInKnapsack(0);
}

// set the data members of class in the state of starting the calculation:
protected void setInitialStateForCalculation()
{
setInKnapsackByAll(0);
calculated = false;
points = 0;
teamSalary = 0;
teamSize = 0;
}

} 
}

Спасибо за помощь!

-121--1365755- Переключение emacs с терминала При запуске терминального режима в Emacs с использованием термина M-x с использованием C-x C-o I не может переключаться на другой буфер для продолжения работы над вещами. Я знаю, что это возможно с оболочкой M-x, но с этой командой...

При запуске терминального режима в Emacs с использованием M-x term с использованием C-x C-o я не могу переключиться на другой буфер для продолжения работы над вещами. Я знаю, что это возможно с M-x shell , но с этой командой есть определенные аспекты оболочки, которые не работают (меньше, больше, man pages и т.д.). Мне было интересно, есть ли способ обойти это или если при использовании терминального режима вы ограничиваетесь буфером, в котором терминал открыт, пока вы не выйдете.

18
задан Jesus Ramos 17 September 2011 в 01:55
поделиться