From 2543573df3fcff12e83b29fdc98eaf21975bfa4c Mon Sep 17 00:00:00 2001 From: voidbert Date: Thu, 14 Mar 2024 01:14:02 +0000 Subject: [PATCH 1/3] Simplified .gitignore and added missing items --- .gitignore | 161 +++-------------------------------------------------- 1 file changed, 8 insertions(+), 153 deletions(-) diff --git a/.gitignore b/.gitignore index 68bc17f..ceaaee6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,160 +1,15 @@ -# Byte-compiled / optimized / DLL files +# Byte-compiled Python __pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide -.pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site # mypy .mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ -# pytype static type analyzer -.pytype/ +# VSCode +.vscode/ -# Cython debug symbols -cython_debug/ +# macOS +.DS_Store -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +# Any compiled report that's not one of the final ones (add those later). +*.pdf +!/TP1/Requirements.pdf From 905b8aeac5bcedd78b70276bd7fd18fc17a1ddca Mon Sep 17 00:00:00 2001 From: Humberto Gomes <50591320+voidbert@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:35:25 +0000 Subject: [PATCH 2/3] GitHub Action to check for incorrect report formatting (#2) * Add script that checks LaTeX formatting * Add GitHub Action for LaTeX format verification --- .github/workflows/format.yml | 11 +++++++++++ latexformat.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 .github/workflows/format.yml create mode 100755 latexformat.sh diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml new file mode 100644 index 0000000..d5d5668 --- /dev/null +++ b/.github/workflows/format.yml @@ -0,0 +1,11 @@ +name: Report formatting +on: [ pull_request ] +jobs: + format: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + # clang-format doesn't come with act's local images. This is just for testing, as + # scripts contain + - run: ./latexformat.sh diff --git a/latexformat.sh b/latexformat.sh new file mode 100755 index 0000000..78ad435 --- /dev/null +++ b/latexformat.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +retval=0 +for file in $(find . -type f -name "*.tex"); do + i=1 + while IFS="" read -r line; do + if printf "%s" "$line" | grep -P '\t' > /dev/null; then + echo "$file:$i Use of tabs! \"$line\"" >&2 + retval=1 + fi + + if printf "%s" "$line" | grep -P '[\t ]$' > /dev/null; then + echo "$file:$i Trailing whitespace! \"$line\"" >&2 + retval=1 + fi + + if [ $(printf "%s" "$line" | wc -m) -gt 100 ]; then + echo "$file:$i Column limit of 100 surpassed! \"$line\"" >&2 + retval=1 + fi + + i=$(($i + 1)) + done < "$file" +done + +exit $retval From 92878e2986cad493719973ce0136b21dd6a7c08f Mon Sep 17 00:00:00 2001 From: Humberto Gomes <50591320+voidbert@users.noreply.github.com> Date: Tue, 19 Mar 2024 21:07:00 +0000 Subject: [PATCH 3/3] Add metaprogramming section and conclusion (#4) * Add description of both scripts * Fix typo * Finish meta-programming part * Add conclusion * Polished metaprogramming section and conclusion --- TP1/Report.tex | 141 ++++++++++++++++++++++++++++++++++++++++-------- TP1/dyckhoff.py | 2 +- 2 files changed, 121 insertions(+), 22 deletions(-) diff --git a/TP1/Report.tex b/TP1/Report.tex index 6fe5443..bb1f675 100644 --- a/TP1/Report.tex +++ b/TP1/Report.tex @@ -4,11 +4,14 @@ \usepackage[portuguese]{babel} \usepackage{cite} \usepackage{enumerate} -\usepackage[a4paper, margin=2cm]{geometry} \usepackage{float} +\usepackage[a4paper, margin=2cm]{geometry} \usepackage{graphicx} \usepackage{hyperref} +\usepackage{listings} +\usepackage{lscape} \usepackage{setspace} +\usepackage{xcolor} \chardef\_=`_ @@ -38,11 +41,11 @@ \begin{abstract} Este trabalho prático de Investigação Operacional tem como objetivo a resolução de um problema - de empacotamento a uma dimensão utilizando o modelo de "um-corte", de Dyckhoff. \cite{dyckhoff} - Em detalhe, procura-se a formulação do problema, a sua modelação, a sua resolução, e a validação - do modelo construído. - - % TODO - adicionar que fizemos meta programação + de empacotamento a uma dimensão utilizando o modelo de "um-corte"{}, de Dyckhoff. + \cite{dyckhoff} Em detalhe, procura-se a formulação do problema, a sua modelação, a sua + resolução, e a validação do modelo construído. Para tornar o processo de modelação mais rápido e + menos propício a erros, o nosso grupo implementou conceitos de metaprogramação ao escrever um + \emph{script} Python que automaticamente gera o código LP do modelo. \end{abstract} \setcounter{section}{-1} @@ -63,7 +66,7 @@ \section{Dados do problema} \end{tabular} \end{center} \caption{Número de contentores de cada comprimento disponíveis.} - \label{containers-data} + \label{containers-data} \end{table} \begin{table}[H] @@ -79,7 +82,7 @@ \section{Dados do problema} \end{tabular} \end{center} \caption{Número de itens de cada comprimento para empacotar.} - \label{items-data} + \label{items-data} \end{table} A soma dos comprimentos dos itens a empacotar é dada por: @@ -104,29 +107,86 @@ \section{Formulação do problema} \section{Metaprogramação} -No modelo de um-corte, a expansão dos sumatórios da função objetivo e das restrições do modelo é, -por vários motivos, difícil de executar manualmente. Devido à grande dimensão dos sumatórios, o -processo não só é demorado, como também propício a erros de cálculo difíceis de diagnosticar: uma -solução errada ou a sua ausência apenas indica a existência de um erro, mas não a sua localização -no modelo. Ademais, a recriação do modelo teria de ser repetida caso os dados iniciais do problema -sofressem alterações, uma ocorrência constante no mundo real. Para endereçar este problema, -desenvolvemos \emph{scripts} em Python que geram o modelo LP automaticamente. +A expansão dos vários sumatórios do modelo de "um-corte"{} é, devido à sua dimensão, difícil de ser +executada manualmente. O processo não só é demorado, como também propício a erros de cálculo +difíceis de diagnosticar: uma solução errada ou a ausência de solução no modelo final apenas indica +a existência de um erro, mas não a sua localização. Ademais, o processo laborioso de criação do +modelo teria de ser repetido caso os dados iniciais do problema sofressem alterações, uma ocorrência +constante no mundo real. Para endereçar este problema, desenvolvemos \emph{scripts} em Python que +geram o modelo LP automaticamente. -\subsection{Modelo do um-corte} +\subsection{Modelo de "um-corte"{}} -% TODO - Descrição do modelo dos um-cortes +O nosso \emph{script} para a implementação deste modelo encontra-se em anexo (ver +\ref{code:one-cut}) e o seu funcionamento passo a passo é descrito abaixo. + +% TODO - citar fórmulas do modelo matemático neste relatório + +\begin{enumerate}[\hspace{1cm} \bfseries 1.] + \item Calcular o conjunto de resíduos ($R$), sucessivamente executando todos os cortes possíveis + com base nas capacidades dos contentores e nos comprimentos dos itens. + + \item Gerar a função objetivo, em particular, a variação que não diminui o custo de uma solução + caso tenham sobrado espaços com comprimentos no conjunto das capacidades dos contentores + (isto apenas faz sentido em problemas de corte). É necessária a geração de variáveis e + restrições auxiliares para se calcular o máximo entre $0$ e o custo dos contentores gastos. + + \item Gerar as restrições de equilíbrio, calculando os conjuntos e os sumatórios descritos no + artigo. + + \item Gerar restrições a afirmar que o número de contentores de um dado tipo utilizados não pode + ser superior à disponibilidade dessa capacidade de contentor. + + \item Restringir todas as variáveis de corte a valores inteiros. +\end{enumerate} + +No nosso \emph{script}, a remoção de variáveis redundantes é feita no processo de simplificação de +adições, tanto na geração da função objetivo como das restrições: +$(y_{10, 2}) + (y_{10, 8} + y_{8, 4})$ será automaticamente transformada em $y_{10, 8} + y_{8, 4}$, +por exemplo. \subsection{Modelo dos padrões de corte} Inicialmente, o nosso grupo resolveu o problema de empacotamento proposto utilizando o modelo dos -padrões de corte, de modo a poder verificar a solução do modelo do um-corte quando este fosse -implementado. Também desenvolvemos um \emph{script} que gera este modelo automaticamente, cujo -funcionamento é descrito brevemente: +padrões de corte, de modo a poder verificar a solução do modelo de "um-corte"{} quando este fosse +implementado. Também desenvolvemos um \emph{script} que gera o modelo de Gilmore e Gomory +automaticamente, cujo funcionamento passo a passo é descrito abaixo, e cujo código se encontra em +anexo (ver \ref{code:cutting-patterns}). Como o foco deste trabalho não é o modelo dos padrões de +corte, este não é descrito em detalhe, pelo que é recomendada a leitura do artigo que o definiu. +\cite{gilmore-and-gomory} \begin{enumerate}[\hspace{1cm} \bfseries 1.] - \item % TODO - descrição do modelo dos padrões de corte + \item Calcular os padrões de corte para cada contentor, dado o comprimento de cada item a + empacotar. Isto é implementado recursivamente: procura-se cortar um comprimento em duas + partes menores, uma das quais é o comprimento de um item. Calculam-se os padrões de corte da + outra parte, e usa-se esse resultado para construir os padrões de corte relativos ao + comprimento total. Um comentário LP é gerado para enumerar todos os padrões de corte + calculados. + + \item Gerar a função objetivo: conhecem-se todas as variáveis de decisão (padrões de corte), + cujos coeficientes são as capacidades dos contentores a que estão associadas, dado que se + pretende minimizar a soma das capacidades dos contentores utilizados. + + \item Calcular quanto cada padrão de corte permite empacotar de cada item, e usar essa + informação para gerar restrições que obrigam a que pelo menos um dado número de cada item + seja empacotado. + + \item Gerar restrições relativas ao número máximo de contentores de cada capacidade: a soma de + todos os padrões de corte usados que envolvem contentores de uma capacidade não pode ser + superior à disponibilidade desses contentores. + + \item Registar que todas as variáveis correspondentes a padrões de corte são inteiras. \end{enumerate} +\section{Conclusão} + +Ao longo do desenvolvimento deste trabalho, não só fomos capazes de resolver o problema proposto +com correção, como também obtivemos um profundo conhecimento de dois modelos para a resolução de +problemas de empacotamento a uma dimensão. Este conhecimento permitiu-nos implementar programas que +constroem estes modelos sem qualquer intervenção humana, tornando a sua aplicação mais simples em +problemas maiores e em contextos em que os dados estão em constante mudança, evitando o desperdício +de horas humanas em cálculos que facilmente podem ser executados por um computador. + % Isto é uma grande gambiarra, mas funciona para pôr a bibliografia como uma secção. \section{Bibliografia} \def\refname{} @@ -136,6 +196,45 @@ \section{Bibliografia} H. Dyckhoff, "A New Linear Programming Approach to the Cutting Stock Problem", \emph{Operations Research}, vol. 29, no. 6, Dec., pp. 1092-1104, 1981. \href{https://doi.org/10.1287/opre.29.6.1092}{doi: 10.1287/opre.29.6.1092} + + \bibitem{gilmore-and-gomory} + P. Gilmore, and R. Gomory, "A Linear Programming Approach to the Cutting Stock Problem", + \emph{Operations Research}, vol. 9, no. 6, Dec., pp. 849-859, 1961. + \href{https://doi.org/10.1287/opre.9.6.849}{doi: 10.1287/opre.9.6.849} \end{thebibliography} +\section{Anexos} + +\lstdefinestyle{codestyle}{ + commentstyle=\color{teal}, + keywordstyle=\color{blue}, + numberstyle=\ttfamily\color{gray}, + stringstyle=\color{red}, + basicstyle=\ttfamily\footnotesize, + breakatwhitespace=false, + breaklines=false, + keepspaces=true, + numbers=left, + numbersep=10pt, + showspaces=false, + showstringspaces=false, + showtabs=false, + tabsize=4, + xleftmargin=3em +} +\lstset{style=codestyle} + +\begin{landscape} + + \subsection{\emph{Script} gerador do modelo de "um-corte"{}} +\label{code:one-cut} +\lstinputlisting[language=python]{dyckhoff.py} +\pagebreak + +\subsection{\emph{Script} gerador do modelo de padrões de corte} +\label{code:cutting-patterns} +\lstinputlisting[language=python]{gilmore_gomory.py} + +\end{landscape} + \end{document} diff --git a/TP1/dyckhoff.py b/TP1/dyckhoff.py index 92740e7..b6c63b7 100755 --- a/TP1/dyckhoff.py +++ b/TP1/dyckhoff.py @@ -172,5 +172,5 @@ def output_model(containers: Containers, items: Items) -> str: # Our problem's data print(output_model({11: None, 10: 5, 7: 5}, {2: 13, 4: 9, 5: 5}), end='') - # Example from Dyckhoff's onde-cut model: + # Example from Dyckhoff's one-cut model: # print(output_model({5: None, 6: None, 9: None}, {2: 20, 3: 10, 4: 20}), end='')