Skip to content

Commit

Permalink
Arreglo algunos errores
Browse files Browse the repository at this point in the history
  • Loading branch information
sponja23 committed Sep 24, 2024
1 parent 2a8a106 commit cb25ab1
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 16 deletions.
20 changes: 10 additions & 10 deletions chapters/1-tecnicas-de-diseño.tex
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,11 @@ \subsection{Notación O}
\subsubsection{Complejidades comunes}

\begin{itemize}
\item Si un algoritmo es\BigO{\log{n}}, se dice \textbf{logarítmico}.
\item Si un algoritmo es\BigO{n}, se dice \textbf{lineal}.
\item Si un algoritmo es\BigO{n^2}, se dice \textbf{cuadrático}.
\item Si un algoritmo es\BigO{n^3}, se dice \textbf{cúbico}.
\item Si un algoritmo es\BigO{n^k}, se dice \textbf{polinomial}.
\item Si un algoritmo es \BigO{\log{n}}, se dice \textbf{logarítmico}.
\item Si un algoritmo es \BigO{n}, se dice \textbf{lineal}.
\item Si un algoritmo es \BigO{n^2}, se dice \textbf{cuadrático}.
\item Si un algoritmo es \BigO{n^3}, se dice \textbf{cúbico}.
\item Si un algoritmo es \BigO{n^k}, se dice \textbf{polinomial}.
\item Si un algoritmo es $\BigO{k^n}\ (k > 1)$, se dice \textbf{exponencial}.
\end{itemize}

Expand Down Expand Up @@ -239,7 +239,7 @@ \subsubsection{Ejemplo: Cálculo de coeficientes binomiales}
\End
\end{codebox}

Este método tiene una complejidad de\BigOmega{\binom{n}{k}}, y evita calcular factoriales, pero podría ser más eficiente, ya que al ejecutarlo se repiten llamadas con los mismos parámetros.
Este método tiene una complejidad de \BigOmega{\binom{n}{k}}, y evita calcular factoriales, pero podría ser más eficiente, ya que al ejecutarlo se repiten llamadas con los mismos parámetros.
\begin{figure}[H]
\centering
\includegraphics[width=0.8\textwidth]{combinatorio_call_tree.jpg}
Expand All @@ -263,7 +263,7 @@ \subsubsection{Ejemplo: Cálculo de coeficientes binomiales}
\End
\end{codebox}

La complejidad de este método es\BigO{nk}, y $\BigO{nk} \subseteq \BigO{n^2}$, ya que $k \leq n$. Además, se puede implementar con una complejidad espacial de\BigO{k} almacenando solo la fila actual y la anterior de la tabla en el ciclo.
La complejidad de este método es \BigO{nk}, y $\BigO{nk} \subseteq \BigO{n^2}$, ya que $k \leq n$. Además, se puede implementar con una complejidad espacial de \BigO{k} almacenando solo la fila actual y la anterior de la tabla en el ciclo.

\subsection{Principio de optimalidad de Bellman}
\label{optimalidad-bellman}
Expand Down Expand Up @@ -297,7 +297,7 @@ \subsubsection{Ejemplo: Problema de la mochila}

Esto contempla, para cada $k$ dos posibilidades: o bien el objeto de índice $k$ está en la solución óptima, y entonces $m(k, D) = b_k + m(k - 1, D - p_k)$, o bien no, en cuyo caso $m(k, D) = m(k - 1, D)$.

Si esta función se implementa directamente en un algoritmo de PD (ya sea top-down o bottom-up) utilizando una matriz como estructura de memoización, tanto la complejidad temporal como la espacial son\BigO{nC}. Esta complejidad es \textit{pseudopolinomial}: está acotada por un polinomio, pero este incluye valores númericos del input, no solo el tamaño del mismo.
Si esta función se implementa directamente en un algoritmo de PD (ya sea top-down o bottom-up) utilizando una matriz como estructura de memoización, tanto la complejidad temporal como la espacial son \BigO{nC}. Esta complejidad es \textit{pseudopolinomial}: está acotada por un polinomio, pero este incluye valores númericos del input, no solo el tamaño del mismo.

\subsubsection{Solución óptima}
\label{reconstruccion-solucion}
Expand Down Expand Up @@ -363,7 +363,7 @@ \subsubsection{Ejemplo: Problema de la mochila}
\item ...maximice $\frac{b_i}{p_i}$ (la ``densidad'').
\end{enumerate}

Se puede demostrar que, si se corre el algoritmo goloso $2$ veces, una con el primer criterio y otra con el segundo, alguno de los resultados tiene un valor de al menos la mitad de la solución óptima. Esto hace al procedimiento un algoritmo $\frac{1}{2}$-aproximado, y se puede implementar en tiempo\BigO{n\log{n}} si se ordenan los elementos previamente (es aún más eficiente usar una colas de prioridad implementadas con heap).
Se puede demostrar que, si se corre el algoritmo goloso $2$ veces, una con el primer criterio y otra con el segundo, alguno de los resultados tiene un valor de al menos la mitad de la solución óptima. Esto hace al procedimiento un algoritmo $\frac{1}{2}$-aproximado, y se puede implementar en tiempo \BigO{n\log{n}} si se ordenan los elementos previamente (es aún más eficiente usar una colas de prioridad implementadas con heap).

Por otro lado, si cambia el problema, permitiendo poner una \underline{fracción} de cada elemento en la mochila, el algoritmo goloso que utiliza el tercer criterio devuelve soluciones óptimas.

Expand Down Expand Up @@ -402,7 +402,7 @@ \subsubsection{Ejemplo: Tiempo de espera total en un sistema}

Se puede plantear el siguiente algoritmo goloso: En cada paso, atender al cliente pendiente que tenga el menor tiempo de atención. La idea detrás de ese criterio es que el tiempo de los clientes que son atendidos primero tendrá que ser esperado por todos los demás, así que lo ideal es que sea el mínimo. Formalmente, la solución $I = (i_1, ..., i_n)$ es una que cumple $t_{i_j} \leq t_{i_{j+1}}$ para $j = 1, ..., n - 1$.

En este caso, la solución que proporciona el algoritmo resulta ser óptima. Por otro lado, la complejidad temporal es\BigO{n\log{n}}, ya que el procedimiento es equivalente a ordenar a los clientes por tiempo de espera.
En este caso, la solución que proporciona el algoritmo resulta ser óptima. Por otro lado, la complejidad temporal es \BigO{n\log{n}}, ya que el procedimiento es equivalente a ordenar a los clientes por tiempo de espera.

\section{Algoritmos Probabilísticos}

Expand Down
6 changes: 3 additions & 3 deletions chapters/2-intro-teoria-de-grafos.tex
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ \subsubsection{Matriz de adyacencia}

La matriz es simétrica para grafos, pero no necesariamente para digrafos.

La estructura permite comprobar si dos vértices son adyacentes en tiempo constante. Sin embargo, construirla a partir de una lista de adyacencia es una operación de complejidad cuadrática, y la estructura es muy rígida (para agregar un vértice se debe armar una nueva matriz). Además, la complejidad espacial es también\BigO{|V|^2}, lo cual es problemático para guardar grafos ralos\footnote{Un grafo \textit{ralo} es uno con ``pocas'' aristas.}.
La estructura permite comprobar si dos vértices son adyacentes en tiempo constante. Sin embargo, construirla a partir de una lista de adyacencia es una operación de complejidad cuadrática, y la estructura es muy rígida (para agregar un vértice se debe armar una nueva matriz). Además, la complejidad espacial es también \BigO{|V|^2}, lo cual es problemático para guardar grafos ralos\footnote{Un grafo \textit{ralo} es uno con ``pocas'' aristas.}.

\subsubsection{Matriz de incidencia}

Expand Down Expand Up @@ -440,7 +440,7 @@ \subsection{DFS}
\li $\id{fin}[v] \gets \id{contador}$
\end{codebox}

El tiempo de ejecución del algoritmo, al igual que BFS, es lineal\footnote{La linealidad de estas complejidades se refiere a que, como los grafos se pasan como listas de adyacencia, el tamaño de la entrada es $|E|$. Si se considerara la cantidad de vértices, una complejidad de\BigO{|E|} sería cuadrática, ya que $|E| \in \BigO{|V|^2}$.}: hay una llamada por cada nodo, y cada llamada tiene un tiempo de ejecución proporcional al grado del nodo, así que la complejidad es $\BigO{|V| + |E|}$.
El tiempo de ejecución del algoritmo, al igual que BFS, es lineal\footnote{La linealidad de estas complejidades se refiere a que, como los grafos se pasan como listas de adyacencia, el tamaño de la entrada es $|E|$. Si se considerara la cantidad de vértices, una complejidad de \BigO{|E|} sería cuadrática, ya que $|E| \in \BigO{|V|^2}$.}: hay una llamada por cada nodo, y cada llamada tiene un tiempo de ejecución proporcional al grado del nodo, así que la complejidad es $\BigO{|V| + |E|}$.

Al terminar, DFS no solo devuelve el árbol generado $T$, sino que también un par de arreglos \id{principio} y \id{fin}. El primero guarda el orden en el que se empieza a explorar el subárbol de cada nodo (también llamado \textit{pre-order}), mientras que el segundo guarda el orden en el que se termina dicha exploración (también llamado \textit{post-order}). Estos valores son muy útiles para analizar la estructura del árbol.

Expand Down Expand Up @@ -533,7 +533,7 @@ \subsection{Algoritmo}
Como el valor de \id{fin}[$v$] se asigna después de haber explorado por todos los vértices $u$ alcanzables desde $v$, se cumple que $\id{fin}[u] < \id{fin}[v]$. Por ende, si se ordenan los vértices por valor \id{fin} decreciente, los vértices que se pueden alcanzar desde otros aparecerán después.
\end{proof}

Para implementar este algoritmo, no es necesario ordenar directamente los vértices a través de \id{fin} (lo tendría complejidad\BigO{|V|\log{|V|}}), sino que basta con modificar DFS: después de terminar de explorar el subárbol de cada vértice, se lo agrega al principio de una secuencia. Esto produce un ordenamiento topológico de $D$.
Para implementar este algoritmo, no es necesario ordenar directamente los vértices a través de \id{fin} (lo tendría complejidad \BigO{|V|\log{|V|}}), sino que basta con modificar DFS: después de terminar de explorar el subárbol de cada vértice, se lo agrega al principio de una secuencia. Esto produce un ordenamiento topológico de $D$.

\section{Algoritmo de Kosaraju}

Expand Down
6 changes: 3 additions & 3 deletions chapters/6-np-completitud.tex
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ \subsection{Máquina de Turing Determinística}

Esas son las características generales de cualquier MTD. Para una máquina particular, se tiene:
\begin{itemize}
\item Un \textit{alfabeto} de \textit{símbolos} finito $\Sigma$ y un símbolo especial $\ast$ llamado ``\textit{blanco}''. Se define $\Gamma = \Sigma \cup \{\ast\}$. La celda puede tomar valores en $\Gamma$.
\item Un \textit{alfabeto} de \textit{símbolos} finito $\Sigma$ y un símbolo especial $\ast$ llamado ``\textit{blanco}''. Se define $\Gamma = \Sigma \cup \{\ast\}$. Las celdas puede tomar valores en $\Gamma$.
\item Un conjunto finito $Q$ de \textit{estados}.
\item Un \textit{estado inicial} $q_0 \in Q$.
\item Un conjunto de \textit{estados finales} $Q_f \subseteq Q$ (en el caso de problemas de optimización $Q_f = \{q_{\text{sí}}, q_{\text{no}}\}$).
Expand All @@ -77,7 +77,7 @@ \subsubsection{Resolución y Complejidad}
La máquina \textit{resuelve} el problema $\Pi$ si para toda instancia $I \in I_{\Pi}$ esta alcanza un estado final y es el correcto.

La \textit{complejidad} de una MTD está dada por la cantidad de movimientos de la cabeza que se realizan entre el estado inicial y el final, en función del tamaño de entrada:
$$T_M(n) = \max\{m \mid M \text{ realiza $m$ movimientos para la entrada $I \in I_{@P}, |I| = n$}\}$$
$$T_M(n) = \max\{m \mid M \text{ realiza $m$ movimientos para la entrada $I \in I_{\Pi}, |I| = n$}\}$$

Una MTD $M$ es \textit{polinomial} para $\Pi$ cuando $T_M(n) \in \BigO{n^k}$ para algún $k$.

Expand Down Expand Up @@ -112,7 +112,7 @@ \subsection{La clase NP}
Si $\Pi$ es un problema de decisión que pertenece a la clase NP, entonces $\Pi$ puede ser resuelto por un algoritmo determinístico en tiempo exponencial con respecto al tamaño de la entrada.
\end{theorem*}
\begin{proof}
Para resolver $\Pi$, se puede simular la ejecución de la MTND que lo resuelve: cada vez que hay ambigüedad con respecto a la instrucción a aplicar se exploran todos los ``súbarboles de ejecución''. Esto implica una complejidad exponencial: si hay a lo sumo $A$ estados distintos para cada punto de no-determinismo, se realizan \BigO{A^{T_M(n)}}, y $T_M(n)$ es una función exponencial (porque $\Pi \in \text{NP}$).
Para resolver $\Pi$, se puede simular la ejecución de la MTND que lo resuelve: cada vez que hay ambigüedad con respecto a la instrucción a aplicar se exploran todos los ``súbarboles de ejecución''. Esto implica una complejidad exponencial: si hay a lo sumo $A$ estados distintos para cada punto de no-determinismo, se realizan \BigO{A^{T_M(n)}}, y $T_M(n)$ es una función polinomial (porque $\Pi \in \text{NP}$).
\end{proof}

\subsubsection{P vs. NP}
Expand Down

0 comments on commit cb25ab1

Please sign in to comment.