Sou tutor de práticas de laboratório na universidade, com base nos comentários dos alunos do ano passado, queríamos que eu e meu chefe os abordássemos. Meu chefe optou por escrever um script C e eu escolhi python (python-constraint) para tentar resolver nosso problema.
Informações
- Existem 6 sessões
- Existem 4 papéis
- Existem 6 práticas
- Existem 32 alunos
- Há 4 alunos por equipe
Problema:
Designe cada aluno para 4 funções, em 4 práticas em 4 sessões diferentes.
Restrições :
- Os alunos devem desempenhar um papel uma vez
- Os alunos devem praticar 4 práticas diferentes em 6
- Os alunos devem praticar apenas uma prática por sessão
- O aluno deve encontrar o mesmo companheiro apenas uma vez
Modelos :
Aqui está o modelo que eu sinto com os alunos, onde cada equipe é composta por 4 alunos, as posições [0, 1, 2 ou 3] são funções atribuídas a eles. Cada posição disponível está numerada de 1 a 128
[# Semester
[ # Session
[ # Practice/Team
1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]],
[[25, 26, 27, 28],
[29, 30, 31, 32],
[33, 34, 35, 36],
[37, 38, 39, 40],
[41, 42, 43, 44],
[45, 46, 47, 48]],
[[49, 50, 51, 52],
[53, 54, 55, 56],
[57, 58, 59, 60],
[61, 62, 63, 64],
[65, 66, 67, 68],
[69, 70, 71, 72]],
[[73, 74, 75, 76],
[77, 78, 79, 80],
[81, 82, 83, 84],
[85, 86, 87, 88],
[89, 90, 91, 92],
[93, 94, 95, 96]],
[[97, 98, 99, 100],
[101, 102, 103, 104],
[105, 106, 107, 108],
[109, 110, 111, 112]],
[[113, 114, 115, 116],
[117, 118, 119, 120],
[121, 122, 123, 124],
[125, 126, 127, 128]]]
Em outras palavras :
Esta é uma sessão:
[[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20],
[21, 22, 23, 24]],
Essas equipes fazem a mesma prática:
[
[1, 2, 3, 4],
[25, 26, 27, 28],
[49, 50, 51, 52],
[73, 74, 75, 76],
[97, 98, 99, 100],
[113, 114, 115, 116]
]
Essas posições desempenham o mesmo papel:
[
1,
5,
9,
13,
17,
21,
25,
...
]
O que tenho até agora:
Usando python-constraint, pude validar as três primeiras restrições:
Valid solution : False
- sessions : [True, True, True, True, True, True]
- practices : [True, True, True, True, True, True]
- roles : [True, True, True, True]
- teams : [False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False]
Para aqueles que podem ser interessantes, eu simplesmente faço assim:
Para cada condição eu uso AllDifferentConstraint . Por exemplo, para uma sessão eu faço:
problem.addConstraint(AllDifferentConstraint(), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
Não consigo encontrar uma maneira de restringir a equipe, minha última tentativa no geral semester
foi a seguinte:
def team_constraint(self, *semester):
students = defaultdict(list)
# get back each teams based on the format [# Semester [ #Session [# Practice/Team ...
teams = [list(semester[i:i+4]) for i in range(0, len(semester), 4)]
# Update Students dict with all mate they work with
for team in teams:
for student in team:
students[student] += [s for s in team if s != student]
# Compute for each student if they meet someone more than once
dupli = []
for student, mate in students.items():
dupli.append(len(mate) - len(set(mate)))
# Loosly constraint, if a student meet somone 0 or one time it's find
if max(dupli) >= 2:
print("Mate encounter more than one time", dupli, min(dupli) ,max(dupli))
return False
pprint(students)
return True
Questões :
- É possível fazer o que eu quero para as condições da equipe? O que quero dizer é que não tenho idéia se é possível atribuir 12 companheiros a cada aluno e cada um deles encontrar o mesmo companheiro apenas uma vez.
- Para a restrição de equipe, perdi um algoritmo de melhor desempenho?
- Qualquer pist que eu possa seguir?
fonte
(4, 4)
não(4, 6)
como os outros?Respostas:
A pergunta principal seria respondida com algo como ...
Edição adicionada
Ontem, olhei para o seu problema - (reconhecidamente não muito tempo, pois tenho muito trabalho no momento) e ...
Antes de tudo, vejo que sua entidade de 'equipe' é praticamente o que chamei de entidade de 'ação' e, em retrospecto, acho que 'equipe' (ou 'grupo') era uma palavra melhor para isso.
Se você ainda estiver achando difícil as restrições, sugiro que você as rompa e trabalhe nelas individualmente - particularmente as restrições de equipe / pessoa / sessão, seguidas pelas restrições de função / tarefa.
/ Edição adicionada
Eu tive um problema semelhante recentemente e, no final, virei para o OR-tools. https://developers.google.com/optimization/cp/cp_solver
Particularmente, dê uma olhada no problema de agendamento da enfermeira: https://developers.google.com/optimization/scheduling/employee_scheduling#nurse_scheduling
De qualquer forma, o problema não é muito complexo, então talvez usar um solucionador seja um exagero para você.
Da mesma forma, para esse tipo de problema, pode ser melhor usar um ditado com chave de tupla para armazenar suas variáveis, em vez de listas aninhadas:
{Equipe, Sessão, Pessoa: BoolVar}
O principal motivo é que você pode aplicar restrições por meio de filtros, o que é muito mais fácil do que ter que manipular listas aninhadas, por exemplo, para aplicar uma restrição entre pessoas / equipes, você pode fazer (onde person é o índice 2 e team é o índice 0):
fonte
p for p in all_people
?Apenas uma idéia do algoritmo de permutação, para cada iteração, poderia ser focada em um de cada aluno ou em uma de cada sessão:
Aqui o aluno 2 substitui o aluno 1 na sessão 1 e continua assim
Continue com o aluno 1 S3 R 1234 St 10,9,1,8
No final, você remove as interações do aluno 1, como nas permutações da próxima iteração, e remove a corrente.
É como um cubo de rubiks.
Se você codificar isso ou souber algum código com esse algo, me avise.
Talvez com as permutações de itertools
Sessões sendo> do que práticas que acredito não são tão relevantes quanto seu número. Apenas um pouco de piscina para levar mais quando você acabar ou mais espaço para a rotação. Talvez pudesse simplificar o problema primeiro com o objetivo de 4 sessões = práticas?
fonte