From 978eebb68eb4c3bd1518ab9be7004a1c8dd09b75 Mon Sep 17 00:00:00 2001 From: Italo Silva Date: Thu, 4 Feb 2016 17:50:59 -0200 Subject: [PATCH] Adiciona README --- README.md | 11 + modelo-grade/arquivos.cpp | 424 +++++++++++++++++++------------------- 2 files changed, 223 insertions(+), 212 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..b596e32 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# README # + +### RESUMO ### +Aplicação que resolve modelos de grades de alunos usando as tecnologias CPLEX e Concert +da IBM. Escrito em C++14, usando Visual Studio 2015 e MSVC 12, pois é o mais recente que o Concert +suporta. + +### DEPENDÊNCIAS ### +* CPLEX 12.63 +* Concert 12.63 +* Microsoft Visual C++ 12 (Visual Studio 2013) diff --git a/modelo-grade/arquivos.cpp b/modelo-grade/arquivos.cpp index 02471dd..759d48f 100644 --- a/modelo-grade/arquivos.cpp +++ b/modelo-grade/arquivos.cpp @@ -10,229 +10,229 @@ std::pair> fagoc::ler_json(std::string arquivo) { - std::ifstream entrada(arquivo); - - // Mapeia os nomes das disciplinas a índices nos vetores e matrizes - std::unordered_map disc_to_int; - - Json::Value raiz; - entrada >> raiz; - - /********************************************** - * ENTRADA DISCIPLINAS * - **********************************************/ - - // Lê uma primeira vez para contar o número de disciplinas e associar - // os nomes a índices - const auto& disciplinas = raiz["disciplinas"]; - std::vector nome_disc; - std::vector creditos; - - for (size_t i = 0; i < disciplinas.size(); i++) { - auto nome = disciplinas[i]["id"].asString(); - nome_disc.push_back(nome); - disc_to_int[nome] = i; - - creditos.push_back(disciplinas[i]["carga"].asInt()); - } - - auto num_disc = creditos.size(); - - // Lê uma segunda vez, dessa vez registrando de fato as disciplinas na memória - std::vector> prerequisitos(num_disc, - std::vector(num_disc, 0)); - std::vector> corequisitos(num_disc, - std::vector(num_disc, 0)); - std::vector> equivalencias(num_disc, - std::vector(num_disc, 0)); - std::vector> disc_turma(num_disc); - std::vector periodo_minimo(num_disc); - std::vector capacidades(num_disc); - - for (size_t i = 0; i < disciplinas.size(); i++) { - const auto& prereq = disciplinas[i]["prerequisitos"]; - const auto& equiv = disciplinas[i]["equivalentes"]; - auto disc_atual = disc_to_int[disciplinas[i]["id"].asString()]; - - for (size_t j = 0; j < prereq.size(); j++) { - auto prereq_atual = disc_to_int[prereq[j].asString()]; - prerequisitos[disc_atual][prereq_atual] = 1; - } - - for (size_t j = 0; j < equiv.size(); j++) { - auto equiv_atual = disc_to_int[equiv[j].asString()]; - equivalencias[disc_atual][equiv_atual] = 1; - } - - disc_turma[disc_atual].first = disciplinas[i]["periodo"].asString(); - disc_turma[disc_atual].second = disciplinas[i]["periodo"].asString(); - capacidades[disc_atual] = disciplinas[i]["capacidade"].asInt(); - periodo_minimo[disc_atual] = disciplinas[i]["periodominimo"].asString(); - } - - /********************************************** - * ENTRADA HORÁRIOS * - **********************************************/ - - // Registra o número de horários, períodos e dias letivos - const auto& horarios = raiz["horario"]; - auto num_horarios_dia = 0; - auto num_dias_letivos = 0; - auto num_periodos = 0; - - for (size_t i = 0; i < horarios.size(); i++) { - auto horario_atual = horarios[i]["horario"].asInt(); - if (horario_atual + 1 > num_horarios_dia) { - num_horarios_dia = horario_atual + 1; - } - - auto dia_letivo_atual = horarios[i]["semana"].asInt(); - if (dia_letivo_atual + 1 > num_dias_letivos) { - num_dias_letivos = dia_letivo_atual + 1; - } - - auto periodo_atual = horarios[i]["camada"].asInt(); - if (periodo_atual + 1 > num_periodos) { - num_periodos = periodo_atual + 1; - } - } - - // Volta e lê o horário novamente, desta vez montando de fato na memória - auto num_horarios = num_horarios_dia * num_dias_letivos; - std::vector> matriz_horario( - num_horarios, std::vector(num_disc, 0)); - std::vector ofertadas(num_disc, 0); - - for (size_t i = 0; i < horarios.size(); i++) { - auto horario_atual = horarios[i]["horario"].asInt(); - auto dia_letivo_atual = horarios[i]["semana"].asInt(); - - auto horario = num_horarios_dia * dia_letivo_atual + horario_atual; - auto disc_index = disc_to_int[horarios[i]["professordisciplina"].asString()]; - - matriz_horario[horario][disc_index] = 1; - ofertadas[disc_index] = 1; - } - - Curso curso(move(creditos), move(prerequisitos), - move(corequisitos), move(matriz_horario), - move(ofertadas), move(equivalencias), - move(disc_turma), move(periodo_minimo), - move(nome_disc), move(capacidades), - num_dias_letivos, num_periodos); - - - /********************************************* - * ENTRADA ALUNOS * - *********************************************/ - - const auto& alunos = raiz["alunoperfis"]; - std::vector vet_alunos; - - for (size_t i = 0; i < alunos.size(); i++) { - auto nome = alunos[i]["id"].asString(); - auto periodo = alunos[i]["periodo"].asString(); - auto turma = alunos[i]["turma"].asString(); - - std::vector aprovacoes(num_disc, 1); - - const auto& restantes = alunos[i]["restantes"]; - for (size_t j = 0; j < restantes.size(); j++) { - auto disc_index = disc_to_int[restantes[j].asString()]; - aprovacoes[disc_index] = 0; - } - - auto cursadas(aprovacoes); - - const auto& disc_cursadas = alunos[i]["cursadas"]; - for (size_t j = 0; j < disc_cursadas.size(); j++) { - auto disc_index = disc_to_int[disc_cursadas[j].asString()]; - cursadas[disc_index] = 1; - } - - vet_alunos.push_back(Aluno(nome, move(aprovacoes), - move(cursadas), - periodo, turma)); - } - - return make_pair(std::move(curso), move(vet_alunos)); + std::ifstream entrada(arquivo); + + // Mapeia os nomes das disciplinas a índices nos vetores e matrizes + std::unordered_map disc_to_int; + + Json::Value raiz; + entrada >> raiz; + + /********************************************** + * ENTRADA DISCIPLINAS * + **********************************************/ + + // Lê uma primeira vez para contar o número de disciplinas e associar + // os nomes a índices + const auto& disciplinas = raiz["disciplinas"]; + std::vector nome_disc; + std::vector creditos; + + for (size_t i = 0; i < disciplinas.size(); i++) { + auto nome = disciplinas[i]["id"].asString(); + nome_disc.push_back(nome); + disc_to_int[nome] = i; + + creditos.push_back(disciplinas[i]["carga"].asInt()); + } + + auto num_disc = creditos.size(); + + // Lê uma segunda vez, dessa vez registrando de fato as disciplinas na memória + std::vector> prerequisitos(num_disc, + std::vector(num_disc, 0)); + std::vector> corequisitos(num_disc, + std::vector(num_disc, 0)); + std::vector> equivalencias(num_disc, + std::vector(num_disc, 0)); + std::vector> disc_turma(num_disc); + std::vector periodo_minimo(num_disc); + std::vector capacidades(num_disc); + + for (size_t i = 0; i < disciplinas.size(); i++) { + const auto& prereq = disciplinas[i]["prerequisitos"]; + const auto& equiv = disciplinas[i]["equivalentes"]; + auto disc_atual = disc_to_int[disciplinas[i]["id"].asString()]; + + for (size_t j = 0; j < prereq.size(); j++) { + auto prereq_atual = disc_to_int[prereq[j].asString()]; + prerequisitos[disc_atual][prereq_atual] = 1; + } + + for (size_t j = 0; j < equiv.size(); j++) { + auto equiv_atual = disc_to_int[equiv[j].asString()]; + equivalencias[disc_atual][equiv_atual] = 1; + } + + disc_turma[disc_atual].first = disciplinas[i]["periodo"].asString(); + disc_turma[disc_atual].second = disciplinas[i]["periodo"].asString(); + capacidades[disc_atual] = disciplinas[i]["capacidade"].asInt(); + periodo_minimo[disc_atual] = disciplinas[i]["periodominimo"].asString(); + } + + /********************************************** + * ENTRADA HORÁRIOS * + **********************************************/ + + // Registra o número de horários, períodos e dias letivos + const auto& horarios = raiz["horario"]; + auto num_horarios_dia = 0; + auto num_dias_letivos = 0; + auto num_periodos = 0; + + for (size_t i = 0; i < horarios.size(); i++) { + auto horario_atual = horarios[i]["horario"].asInt(); + if (horario_atual + 1 > num_horarios_dia) { + num_horarios_dia = horario_atual + 1; + } + + auto dia_letivo_atual = horarios[i]["semana"].asInt(); + if (dia_letivo_atual + 1 > num_dias_letivos) { + num_dias_letivos = dia_letivo_atual + 1; + } + + auto periodo_atual = horarios[i]["camada"].asInt(); + if (periodo_atual + 1 > num_periodos) { + num_periodos = periodo_atual + 1; + } + } + + // Volta e lê o horário novamente, desta vez montando de fato na memória + auto num_horarios = num_horarios_dia * num_dias_letivos; + std::vector> matriz_horario( + num_horarios, std::vector(num_disc, 0)); + std::vector ofertadas(num_disc, 0); + + for (size_t i = 0; i < horarios.size(); i++) { + auto horario_atual = horarios[i]["horario"].asInt(); + auto dia_letivo_atual = horarios[i]["semana"].asInt(); + + auto horario = num_horarios_dia * dia_letivo_atual + horario_atual; + auto disc_index = disc_to_int[horarios[i]["professordisciplina"].asString()]; + + matriz_horario[horario][disc_index] = 1; + ofertadas[disc_index] = 1; + } + + Curso curso(move(creditos), move(prerequisitos), + move(corequisitos), move(matriz_horario), + move(ofertadas), move(equivalencias), + move(disc_turma), move(periodo_minimo), + move(nome_disc), move(capacidades), + num_dias_letivos, num_periodos); + + + /********************************************* + * ENTRADA ALUNOS * + *********************************************/ + + const auto& alunos = raiz["alunoperfis"]; + std::vector vet_alunos; + + for (size_t i = 0; i < alunos.size(); i++) { + auto nome = alunos[i]["id"].asString(); + auto periodo = alunos[i]["periodo"].asString(); + auto turma = alunos[i]["turma"].asString(); + + std::vector aprovacoes(num_disc, 1); + + const auto& restantes = alunos[i]["restantes"]; + for (size_t j = 0; j < restantes.size(); j++) { + auto disc_index = disc_to_int[restantes[j].asString()]; + aprovacoes[disc_index] = 0; + } + + auto cursadas(aprovacoes); + + const auto& disc_cursadas = alunos[i]["cursadas"]; + for (size_t j = 0; j < disc_cursadas.size(); j++) { + auto disc_index = disc_to_int[disc_cursadas[j].asString()]; + cursadas[disc_index] = 1; + } + + vet_alunos.push_back(Aluno(nome, move(aprovacoes), + move(cursadas), + periodo, turma)); + } + + return make_pair(std::move(curso), move(vet_alunos)); } void fagoc::gen_html(const Curso& curso, const std::vector>& solucoes, std::string destino) { - std::ofstream saida{destino + "\\resultado.html"}; - std::ifstream arq_css{arquivo_css}; - std::ostringstream buffer{}; - buffer << arq_css.rdbuf(); - auto css = buffer.str(); - std::ostringstream html_pkg; - - for (const auto& solucao : solucoes) { - html_pkg << gen_html_aluno(curso, *solucao, destino, css); - } - - saida << std::nounitbuf << html_pkg.str() << std::endl; + std::ofstream saida{destino + "\\resultado.html"}; + std::ifstream arq_css{arquivo_css}; + std::ostringstream buffer{}; + buffer << arq_css.rdbuf(); + auto css = buffer.str(); + std::ostringstream html_pkg; + + for (const auto& solucao : solucoes) { + html_pkg << gen_html_aluno(curso, *solucao, destino, css); + } + + saida << std::nounitbuf << html_pkg.str() << std::endl; } std::string fagoc::gen_html_aluno(const Curso& curso, const Solucao& solucao, const std::string& destino, const std::string& css) { - std::ostringstream html; - const std::string dias_semana[] = {"Segunda", "Terça", "Quarta", "Quinta", - "Sexta", "Sábado", "Domingo"}; - - html << std::nounitbuf; - html << "\n" - << "\n" - << "" - << "\n" - << "

" + solucao.nome_aluno + ":

" - << "\n"; - - html << "\n"; - for (auto i = 0; i < curso.num_dias_letivos(); i++) { - html << "\n"; - } - html << "\n"; - - auto horarios_dia = static_cast( - curso.num_horarios() / curso.num_dias_letivos()); - - for (std::size_t i = 0; i < horarios_dia; i++) { - html << "\n"; - for (std::size_t j = 0; j <= curso.num_horarios() - curso.num_periodos(); - j += curso.num_periodos()) { - auto encontrou = false; - for (std::size_t k = 0; k < curso.num_disciplinas(); k++) { - if (curso.horario()[j + i][k] && solucao.solucao_bool[k]) { - html << "\n"; - encontrou = true; - break; - } - } - // Se chegar ao fim de todas as disciplinas e não encontrar nenhuma - // que tenha sido escolhida, imprime um traço indicando slot vazio - if (!encontrou) { - html << "\n"; - } - } - html << "\n"; - } - - html << "
" << dias_semana[i] << "
" - << curso.nome_disciplinas()[k] << " -----
\n" - << "\n" - << "\n"; - - std::ofstream arquivo_saida(destino + "\\" + solucao.nome_aluno + ".html"); - arquivo_saida << std::nounitbuf << html.str() << std::endl; - - // E também retorna a string (a mesma que foi escrita) para quem chamou - return html.str(); + std::ostringstream html; + const std::string dias_semana[] = {"Segunda", "Terça", "Quarta", "Quinta", + "Sexta", "Sábado", "Domingo"}; + + html << std::nounitbuf; + html << "\n" + << "\n" + << "" + << "\n" + << "

" + solucao.nome_aluno + ":

" + << "\n"; + + html << "\n"; + for (auto i = 0; i < curso.num_dias_letivos(); i++) { + html << "\n"; + } + html << "\n"; + + auto horarios_dia = static_cast( + curso.num_horarios() / curso.num_dias_letivos()); + + for (std::size_t i = 0; i < horarios_dia; i++) { + html << "\n"; + for (std::size_t j = 0; j <= curso.num_horarios() - curso.num_periodos(); + j += curso.num_periodos()) { + auto encontrou = false; + for (std::size_t k = 0; k < curso.num_disciplinas(); k++) { + if (curso.horario()[j + i][k] && solucao.solucao_bool[k]) { + html << "\n"; + encontrou = true; + break; + } + } + // Se chegar ao fim de todas as disciplinas e não encontrar nenhuma + // que tenha sido escolhida, imprime um traço indicando slot vazio + if (!encontrou) { + html << "\n"; + } + } + html << "\n"; + } + + html << "
" << dias_semana[i] << "
" + << curso.nome_disciplinas()[k] << " -----
\n" + << "\n" + << "\n"; + + std::ofstream arquivo_saida(destino + "\\" + solucao.nome_aluno + ".html"); + arquivo_saida << std::nounitbuf << html.str() << std::endl; + + // E também retorna a string (a mesma que foi escrita) para quem chamou + return html.str(); }