У меня есть кадр данных pandas, который содержит существующие отношения между тремя идентификаторами: manager_id
, employee_id
, project_id
. Изменив, какие менеджеры управляют какими сотрудниками, мне нужно найти ситуацию, при которой существует наименьшее количество менеджеров на проект.
- Один
manager_id
может иметь несколько employee_ids
- Каждый
employee_id
имеет один manager_id
- Каждый
employee_id
может иметь один или несколько project_ids
- Каждый
project_id
может иметь один или несколько employee_id
Единственным дополнительным условием является то, что каждый менеджер может занять определенное максимальное количество сотрудников (на 10% больше, чем они имеют в настоящее время).
Моей первоначальной мыслью было взять декартово произведение между всеми проектами и менеджерами, чтобы найти все возможные комбинации; ограничить результат сценариями, которые соответствуют максимумам; затем найдите сценарий с наименьшим количеством строк. Пытался добиться этого с помощью:
import pandas as pd
from itertools import permutations
relationship_df = pd.DataFrame({'manager_id': [1,1,2,2,2,2],
'employee_id': [1,2,3,4,5,6],
'project_id': [1,2,1,2,None,None],}
)
# Create a dictionary with all the projects and number of employees working on them
project_df = relationship_df.groupby('project_id')['employee_id'].count()
project_df = project_df.sort_values(ascending = False)
project_dict = project_df.to_dict()
# Create a dictionary with all the managers and number of employees working for them
manager_df = relationship_df.groupby('manager_id')['employee_id'].count()
manager_df = manager_df.sort_values(ascending = False)
manager_dict = manager_df.to_dict()
# Create all the possible permutation orders for the projects:
project_perms = list(permutations(project_dict))
# For each possible permutation, assign the project to the manager until their team is full:
for perm_num, perm in enumerate(project_perms):
for manager, team_size in manager_dict.items():
new_teams = {}
for project in perm:
project_size = project_dict[project]
if sum(new_teams.values()) <= 1.1 * team_size:
new_teams[project] = project_size
Есть ли лучший способ для достижения этого или конкретного пакета / алгоритма, который я должен использовать?