Skip to content

Commit 8151c34

Browse files
committed
refactor: Restricoes: GerarCombinacoesComDisponibilidade; GerarHorarioOptions: DAOs
1 parent d80b1c1 commit 8151c34

File tree

4 files changed

+204
-87
lines changed

4 files changed

+204
-87
lines changed

projeto-gerar-horario/GerarHorario/Dtos/Configuracoes/GerarHorarioOptions.cs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,108 @@ public GerarHorarioOptions(int diaSemanaInicio, int diaSemanaFim, Turma[] turmas
2424
LogDebug = logDebug;
2525
}
2626

27+
public Professor? ProfessorFindById(string professorId)
28+
{
29+
var professor = this.Professores.ToList().Find(professor => professor.Id == professorId);
30+
return professor;
31+
}
32+
33+
public Professor ProfessorFindByIdStrict(string professorId, string? exceptionContext = null)
34+
{
35+
var professor = this.ProfessorFindById(professorId);
36+
37+
if (professor == null)
38+
{
39+
throw new Exception($"Professor não encontrado: {professorId}{exceptionContext}.");
40+
}
41+
42+
return professor;
43+
}
44+
45+
public IEnumerable<Diario> Diarios
46+
{
47+
get
48+
{
49+
foreach (var turma in this.Turmas)
50+
{
51+
foreach (var diario in turma.DiariosDaTurma)
52+
{
53+
yield return diario;
54+
}
55+
}
56+
}
57+
}
58+
59+
public Diario? DiarioFindById(string diarioId)
60+
{
61+
var diario = this.Diarios.ToList().Find(diario => diario.Id == diarioId);
62+
return diario;
63+
}
64+
65+
public Diario DiarioFindByIdStrict(string diarioId, string? exceptionContext = null)
66+
{
67+
var diario = this.DiarioFindById(diarioId);
68+
69+
if (diario == null)
70+
{
71+
throw new Exception($"Diário não encontrado: {diarioId}{exceptionContext}.");
72+
}
73+
74+
return diario;
75+
}
76+
77+
public Turma TurmaFindByIdStrict(string turmaId, string? exceptionContext = null)
78+
{
79+
var turma = this.TurmaFindById(turmaId);
80+
81+
if (turma == null)
82+
{
83+
throw new Exception($"Diário não encontrado: {turmaId}{exceptionContext}.");
84+
}
85+
86+
return turma;
87+
}
88+
89+
public Turma? TurmaFindById(string turmaId)
90+
{
91+
var turma = this.Turmas.ToList().Find(turma => turma.Id == turmaId);
92+
return turma;
93+
}
94+
95+
public Intervalo? HorarioDeAulaByIndex(int horarioDeAulaIndex)
96+
{
97+
var horarioDeAula = this.HorariosDeAula[horarioDeAulaIndex];
98+
return horarioDeAula;
99+
}
100+
public Intervalo HorarioDeAulaFindByIdStrict(int horarioDeAulaIndex, string? exceptionContext = null)
101+
{
102+
var horarioDeAula = this.HorarioDeAulaByIndex(horarioDeAulaIndex);
103+
104+
if (horarioDeAula == null)
105+
{
106+
throw new Exception($"Horário de aula não encontrado: índice {horarioDeAulaIndex}.");
107+
}
108+
109+
return horarioDeAula;
110+
}
111+
112+
public IEnumerable<Diario> DiariosByTurmaId(string turmaId)
113+
{
114+
var turma = this.TurmaFindByIdStrict(turmaId);
115+
116+
foreach (var diario in turma.DiariosDaTurma)
117+
{
118+
yield return diario;
119+
}
120+
}
121+
122+
public bool ProfessorEstaVinculadoAoDiario(string professorId, string diarioId)
123+
{
124+
var diario = this.DiarioFindByIdStrict(diarioId);
125+
var professor = this.ProfessorFindByIdStrict(professorId);
126+
127+
return diario.ProfessorId == professor.Id;
128+
}
27129

28130
public override string ToString()
29131
{

projeto-gerar-horario/GerarHorario/Gerador/GerarHorarioContext.cs

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -27,79 +27,21 @@ public void IniciarTodasAsPropostasDeAula()
2727
{
2828
this.TodasAsPropostasDeAula.Clear();
2929

30-
IEnumerable<(int, int, string, string)> GerarTodasAsCombinacoes()
30+
foreach (var combinacao in Restricoes.GerarCombinacoesComDisponibilidade(this.Options))
3131
{
32-
for (int diaSemanaIso = this.Options.DiaSemanaInicio; diaSemanaIso <= this.Options.DiaSemanaFim; diaSemanaIso++)
33-
{
34-
for (int intervaloIndex = 0; intervaloIndex < this.Options.HorariosDeAula.Length; intervaloIndex++)
35-
{
36-
foreach (var turma in this.Options.Turmas)
37-
{
38-
foreach (var diario in turma.DiariosDaTurma)
39-
{
40-
yield return (diaSemanaIso, intervaloIndex, turma.Id, diario.Id);
41-
}
42-
}
43-
}
44-
}
45-
}
46-
47-
IEnumerable<(int, int, string, string)> GerarCombinacoesComDisponibilidade()
48-
{
49-
foreach (var combinacao in GerarTodasAsCombinacoes())
50-
{
51-
var (diaSemanaIso, intervaloIndex, turmaId, diarioId) = combinacao;
52-
53-
var intervaloAula = this.Options.HorariosDeAula[intervaloIndex];
54-
55-
if (intervaloAula == null)
56-
{
57-
throw new Exception($"Intervalo não encontrado: {intervaloIndex}.");
58-
}
59-
60-
var turma = this.Options.Turmas.ToList().Find(turma => turma.Id == turmaId);
61-
62-
if (turma == null)
63-
{
64-
throw new Exception($"Turma não encontrada: {turmaId}.");
65-
}
66-
67-
var diario = turma.DiariosDaTurma.ToList().Find(diario => diario.Id == diarioId);
68-
69-
if (diario == null)
70-
{
71-
throw new Exception($"Diário não encontrado: {diarioId}.");
72-
}
73-
74-
var professor = this.Options.Professores.ToList().Find(professor => professor.Id == diario.ProfessorId);
75-
76-
if (professor == null)
77-
{
78-
throw new Exception($"Professor não encontrado: {diario.ProfessorId} (diário: {diario.Id}, turma: {turma.Id}).");
79-
}
80-
81-
var disponivelParaTurma = Restricoes.VerificarIntervaloEmDisponibilidades(turma.Disponibilidades, diaSemanaIso, intervaloAula);
82-
var disponivelParaProfessor = Restricoes.VerificarIntervaloEmDisponibilidades(professor.Disponibilidades, diaSemanaIso, intervaloAula);
83-
84-
var disponivel = disponivelParaTurma && disponivelParaProfessor;
85-
86-
if (disponivel)
87-
{
88-
yield return combinacao;
89-
}
90-
}
91-
}
92-
93-
foreach (var combinacao in GerarCombinacoesComDisponibilidade())
94-
{
95-
var (diaSemanaIso, intervaloIndex, turmaId, diarioId) = combinacao;
32+
var propostaDeAula = new PropostaDeAula(
33+
contexto: this,
34+
turmaId: combinacao.turmaId,
35+
diarioId: combinacao.diarioId,
36+
diaSemanaIso: combinacao.diaSemanaIso,
37+
intervaloIndex: combinacao.intervaloIndex
38+
);
9639

97-
var propostaDeAula = new PropostaDeAula(this, turmaId, diarioId, diaSemanaIso, intervaloIndex);
9840
this.TodasAsPropostasDeAula.Add(propostaDeAula);
9941

10042
if (this.Options.LogDebug)
10143
{
102-
Console.WriteLine($"--> init proposta de aula | dia: {diaSemanaIso} | intervalo: {intervaloIndex} | diario: {diarioId}");
44+
Console.WriteLine($"--> init proposta de aula | dia: {combinacao.diaSemanaIso} | intervalo: {combinacao.intervaloIndex} | diario: {combinacao.diarioId}");
10345
}
10446
}
10547

projeto-gerar-horario/GerarHorario/Gerador/Restricoes.cs

Lines changed: 85 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,102 @@
11
using Google.OrTools.Sat;
2+
using Sisgea.GerarHorario.Core.Dtos.Configuracoes;
23
using Sisgea.GerarHorario.Core.Dtos.Entidades;
34

45
namespace Sisgea.GerarHorario.Core;
56

7+
using CombinacaoAula = (int diaSemanaIso, int intervaloIndex, string turmaId, string diarioId);
8+
69
public class Restricoes
710
{
11+
///<summary>
12+
/// UTILITÁRIO: Verifica que um (diaSemanaId, intervalo)
13+
/// pode ocorer em um conjunto de disponibilidades.
14+
///</summary>
815
public static bool VerificarIntervaloEmDisponibilidades(
916
IEnumerable<DisponibilidadeDia> disponibilidades,
10-
int diaSemanaIso,
1117
#pragma warning disable IDE0060 // Remover o parâmetro não utilizado
18+
int diaSemanaIso,
1219
Intervalo intervalo
1320
#pragma warning restore IDE0060 // Remover o parâmetro não utilizado
1421
)
1522
{
23+
Console.WriteLine("[warn]: TODO: VerificarIntervaloEmDisponibilidades: retornar corretamente");
24+
1625
return disponibilidades.Any(disponibilidade =>
1726
{
18-
if (disponibilidade.DiaSemanaIso == diaSemanaIso)
19-
{
20-
// TODO: retornar corretamente
21-
// return Intervalo.VerificarIntervalo(disponibilidade.Intervalo, intervaloAula)
22-
}
27+
// TODO: retornar corretamente
28+
29+
// if (disponibilidade.DiaSemanaIso == diaSemanaIso)
30+
// {
31+
// return Intervalo.VerificarIntervalo(disponibilidade.Intervalo, intervalo)
32+
// }
33+
// return false;
34+
2335
return true;
2436
});
2537
}
2638

39+
///<summary>
40+
/// UTILITÁRIO: Gera uma lista com todas as combinações de aula possíveis
41+
/// sem respeitar nenhum critério.
42+
///</summary>
43+
public static IEnumerable<CombinacaoAula> GerarTodasAsCombinacoesPossiveisInclusiveIndisponiveis(GerarHorarioOptions options)
44+
{
45+
for (int diaSemanaIso = options.DiaSemanaInicio; diaSemanaIso <= options.DiaSemanaFim; diaSemanaIso++)
46+
{
47+
for (int intervaloIndex = 0; intervaloIndex < options.HorariosDeAula.Length; intervaloIndex++)
48+
{
49+
foreach (var turma in options.Turmas)
50+
{
51+
foreach (var diario in options.DiariosByTurmaId(turma.Id))
52+
{
53+
yield return (diaSemanaIso, intervaloIndex, turma.Id, diario.Id);
54+
}
55+
}
56+
}
57+
}
58+
}
59+
60+
///<summary>
61+
/// UTILITÁRIO: Gera uma lista com todas as combinações de aula possíveis,
62+
/// respeitando as disponibilidades da turma e disponibilidades do professor.
63+
///</summary>
64+
public static IEnumerable<CombinacaoAula> GerarCombinacoesComDisponibilidade(GerarHorarioOptions options)
65+
{
66+
foreach (var combinacao in Restricoes.GerarTodasAsCombinacoesPossiveisInclusiveIndisponiveis(options))
67+
{
68+
// =====================================================================================
69+
var intervaloDeTempo = options.HorarioDeAulaFindByIdStrict(combinacao.intervaloIndex);
70+
71+
var turma = options.TurmaFindByIdStrict(combinacao.turmaId);
72+
var diario = options.DiarioFindByIdStrict(combinacao.diarioId);
73+
74+
var professor = options.ProfessorFindByIdStrict(
75+
diario.ProfessorId,
76+
exceptionContext: $" (diário: {diario.Id}, turma: {turma.Id})"
77+
)!;
78+
79+
// =====================================================================================
80+
81+
var disponivelParaTurma = Restricoes.VerificarIntervaloEmDisponibilidades(turma.Disponibilidades, combinacao.diaSemanaIso, intervaloDeTempo);
82+
83+
// ===================================
84+
85+
var disponivelParaProfessor = Restricoes.VerificarIntervaloEmDisponibilidades(professor.Disponibilidades, combinacao.diaSemanaIso, intervaloDeTempo);
86+
87+
// ===================================
88+
89+
var disponivel = disponivelParaTurma && disponivelParaProfessor;
90+
91+
// =====================================================================================
92+
93+
if (disponivel)
94+
{
95+
yield return combinacao;
96+
}
97+
}
98+
}
99+
27100
///<summary>
28101
/// RESTRIÇÃO: Diário: respeitar limite de quantidade máxima na semana.
29102
///</summary>
@@ -77,7 +150,7 @@ public static void AplicarLimiteDeNoMaximoUmDiarioAtivoPorTurmaEmUmHorario(Gerar
77150
}
78151

79152
///<summary>
80-
/// RESTRIÇÃO: PREVENCAO CASO O MESMO PROFESSOR ESTEJA DANDO AULA EM DIAS IGUAIS E EM MESMOS HORARIOS
153+
/// RESTRIÇÃO: Professor: não ter mais de uma aula ativa ao mesmo tempo.
81154
///</summary>
82155
public static void AplicarLimiteDeNoMaximoUmDiarioAtivoPorProfessorEmUmHorario(GerarHorarioContext contexto)
83156
{
@@ -90,11 +163,11 @@ public static void AplicarLimiteDeNoMaximoUmDiarioAtivoPorProfessorEmUmHorario(G
90163
{
91164
var propostas = from propostaDeAula in contexto.TodasAsPropostasDeAula
92165
where
93-
propostaDeAula.DiaSemanaIso == diaSemanaIso
94-
&&
95-
propostaDeAula.IntervaloIndex == intervaloIndex
96-
&&
97-
contexto.Options.Turmas.Any(turma => turma.DiariosDaTurma.Any(diario => diario.ProfessorId == professor.Id))
166+
propostaDeAula.DiaSemanaIso == diaSemanaIso
167+
&&
168+
propostaDeAula.IntervaloIndex == intervaloIndex
169+
&&
170+
contexto.Options.ProfessorEstaVinculadoAoDiario(diarioId: propostaDeAula.DiarioId, professorId: professor.Id)
98171
select propostaDeAula.ModelBoolVar;
99172

100173
contexto.Model.AddAtMostOne(propostas);

projeto-gerar-horario/GerarHorario/Main.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Sisgea.GerarHorario.Core.Dtos.Configuracoes;
1+
using Sisgea.GerarHorario.Core.Dtos.Configuracoes;
22
using Sisgea.GerarHorario.Core.Dtos.Entidades;
33

44
namespace Sisgea.GerarHorario.Core;
@@ -15,9 +15,9 @@ public bool Retorno()
1515
"1",//TURMA
1616
"1A INFORMATICA",//NOME DA TURMA
1717
[
18-
new Diario ("diario:1_3", "turma:1", "1", "disciplina:3", 1),
19-
new Diario ("diario:1_1", "turma:1", "1", "disciplina:1", 3),
20-
new Diario ("diario:1_2", "turma:1", "1", "disciplina:2", 2),
18+
new Diario (Id: "diario:1_3", TurmaId: "turma:1", ProfessorId: "1", DisciplinaId: "disciplina:3", QuantidadeMaximaSemana: 1),
19+
new Diario (Id: "diario:1_1", TurmaId: "turma:1", ProfessorId: "2", DisciplinaId: "disciplina:1", QuantidadeMaximaSemana: 3),
20+
new Diario (Id: "diario:1_2", TurmaId: "turma:1", ProfessorId: "1", DisciplinaId: "disciplina:2", QuantidadeMaximaSemana: 2),
2121
],
2222
[
2323
//
@@ -39,9 +39,9 @@ public bool Retorno()
3939
"2",
4040
"1B INFORMATICA",
4141
[
42-
new Diario ("diario:2_1", "turma:2", "2", "disciplina:4", 1),
43-
new Diario ("diario:2_3", "turma:2", "2", "disciplina:1", 3),
44-
new Diario ("diario:2_2", "turma:2", "2", "disciplina:2", 2),
42+
new Diario (Id: "diario:2_1", TurmaId: "turma:2", ProfessorId: "2", DisciplinaId: "disciplina:4", QuantidadeMaximaSemana: 1),
43+
new Diario (Id: "diario:2_3", TurmaId: "turma:2", ProfessorId: "1", DisciplinaId: "disciplina:1", QuantidadeMaximaSemana: 3),
44+
new Diario (Id: "diario:2_2", TurmaId: "turma:2", ProfessorId: "2", DisciplinaId: "disciplina:2", QuantidadeMaximaSemana: 2),
4545
],
4646
[
4747
//
@@ -85,7 +85,7 @@ public bool Retorno()
8585
new("11:10", "12:00"),
8686
};
8787

88-
var gerarHorarioOptions = new GerarHorarioOptions((int)DiaSemanaIso.SEGUNDA, (int)DiaSemanaIso.SEXTA, turmas, professores, horariosDeAula);
88+
var gerarHorarioOptions = new GerarHorarioOptions((int)DiaSemanaIso.SEGUNDA, (int)DiaSemanaIso.SEXTA, turmas, professores, horariosDeAula, true);
8989

9090
// ====================================================
9191
Console.WriteLine("[debug] vamo chamar o GerarHorario");

0 commit comments

Comments
 (0)