Я пытаюсь придумать алгоритм для сортировки и распределения команд по фиксированному количеству пользователей. Большинство найденных мной алгоритмов предполагают количество групп, на которые нужно разделить; Я хотел бы создать интеллектуальную систему, в которой группы назначаются автоматически (в меру своих возможностей) и прогнозируются на основе общего количества пользователей, а также минимального и максимального количества пользователей в группе.

Примите следующие критерии для каждой группы:

  • Минимум 3 человека в группе
  • Максимум 6 человек в группе
  • Умная группировка по общему количеству пользователей

Вот некоторые из возможностей, основанные на общем количестве пользователей и минимальных / максимальных значениях для каждой группы:

Для 24 участников:

  • 4 группы по 5 человек и 1 группа по 4 человека
  • 6 групп по 4 человека
  • 4 группы по 6 человек

Для 21 участника:

  • 3 группы по 6 человек и 1 группа по 3 человека
  • 3 группы по 5 человек и 1 группа из 6 человек (лучший выбор)

Для 10 участников:

  • 2 группы по 5 человек (лучший выбор)
  • 2 группы по 3 человека и 1 группа из 4 человек

Хотя это и не обязательно, «лучшим выбором» для групп будет равное количество пользователей в каждой группе (например, 10 членов будут 2 группами по 5 человек), если это невозможно (например, 21 член), при этом 5 + 5 + 5 + 6 будет «больше» равно "по количеству членов в группе, чем 6 + 6 + 6 + 3.

0
mousesports 27 Ноя 2016 в 00:50

2 ответа

Лучший ответ

Вот решение на JS для всех, кому интересно https://jsfiddle.net/kp8d0w27/6/

Первый цикл проверяет, можно ли разделить общее количество участников поровну. Если может, сделай это.

Второй цикл будет выполняться только в том случае, если сумма не делится поровну, и будет повторяться до тех пор, пока остаток (по модулю) не станет больше минимального набора и меньше максимального.

Наконец, я использую функцию Lodash под названием chunk, чтобы разделить исходный массив на равные части.

const minNumber = 3
const maxNumber = 6

let divisible = false
let totalGroups = 0
let perGroup = 0

const attendees = ['chris', 'kevin', 'thomas', 'gio', 'nathan', 'michael', 'elyse', 'sarah', 'jacinthe', 'chloe', 'benoit', 'alex', 'darren', 'john']
const totalAttendees = attendees.length

// Can we divide into equal groups?
for (let divider = maxNumber; minNumber <= divider; divider--) {
  totalGroups = totalAttendees / divider

  if (Number.isInteger(totalGroups)) {
    divisible = true
    perGroup = divider
    break
  }
}

// Nope, so divide teams and make sure their between our min and max
if (!divisible) {
  totalGroups = 0;

  for (let j = maxNumber, remainder = 0; minNumber <= j; j--) {
    remainder = totalAttendees % j

    if (remainder >= minNumber && remainder <= maxNumber) {
      perGroup = j;
      break
    }
  }
}

console.log(JSON.stringify(_.chunk(attendees, perGroup)))

Не самый чистый (и есть некоторые ситуации, которые я здесь не учел, например, если количество участников меньше минимального), я все еще занимаюсь рефакторингом, но он работает хорошо и решает мою исходную проблему.

0
mousesports 24 Дек 2016 в 21:46

С критерием, который вы указали до сих пор - минимальное изменение размера группы - количество дел ограничено.

  • Если цель кратна 3, 4 или 5, разделите на группы равного размера. (Нам никогда не нужны группы размером 6).
  • В противном случае цель - 1 или 2 (мод 3).
    • Для случая мода 1 используйте одну группу из 4, а все остальные - 3.
    • Для случая мода 2 используйте две группы по 4, остальные - 3.

Обратите внимание, что для 21 вы упустили очевидный выбор из 7 групп по 3 человека.

По этому алгоритму:

  • 24-8 групп по 3 человека
  • 21-7 групп по 3 человека
  • 10 - 2 группы по 3 человека, 1 группа из 4 человек (случай 1 (mod 3))
  • 14 - 2 группы по 3 человека, 2 группы по 4 человека (случай 2 (mod 3))

Может быть, вы тихо думаете (но не говорите), что также хотели бы минимизировать количество групп. Если это правда, то вам необходимо указать относительную важность небольшого количества групп и вариации размера групп. Эти два фактора требуют компромисса.

0
Gene 23 Дек 2016 в 16:13