college/Spring-2023/CS-2233/Notes.org

429 lines
19 KiB
Org Mode
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

* Discrete Math Notes [2024-03-30 Sat 22:51] :journal:cs2233:college:discrete_math:
** Laws of Propositional Logic
:PROPERTIES:
:ID: 539a691a-ce6d-4711-84ba-57e74ed42f27
:END:
*** Domination Laws
- $p ∧ F ≡ F$
- $p ≡ T$
*** Double Negation Law
- $¬¬p ≡ p$
*** Complement Laws
- $p ∧ ¬p ≡ F$
- $¬T ≡ F$
- $p ¬p ≡ T$
- $¬F ≡ T$
*** De Morgan's Laws
- $¬(p q) ≡ ¬p ∧ ¬q$
- $¬(p ∧ q) ≡ ¬p ¬q$
*** Absorption Laws
- $p (p ∧ q) ≡ p$
- $p ∧ (p q) ≡ q$
*** Idempotent Laws
- $p p ≡ p$
- $p ∧ p ≡ p$
*** Associative Laws
Modifying the location of grouping doesn't modify the output among like operators.
- $(p q) r ≡ p (q r)$
- $(p ∧ q) ∧ r ≡ p ∧ (q ∧ r)$
*** Commutative Laws
Modifying the location of variables doesn't modify the output around like operators.
- $(p q) ≡ (q p)$
- $(p ∧ q) ≡ (q ∧ p)$
*** Distributive Laws
- $p (q ∧ r) ≡ (p q) ∧ (p r)$
- $p ∧ (q r) ≡ (p ∧ q) (p ∧ r)$
*** Identity Laws
- $p F ≡ p$
- $p ∧ T ≡ T$
*** Conditional Identities
- $p → q ≡ ¬p q$
- $p ↔ q ≡ (p → q) ∧ (q → p)$
** Even and Odd Integers
- An integer $x$ is /*even*/ if there is an integer $k$ such that $x = 2k$
- An integer $x$ is /*odd*/ if there is an integer $k$ such that $x = 2k + 1$
** Parity
- The /*parity*/ of a number is whether the number is odd or even. If two numbers are both even
or both odd, then the two numbers have the /*same parity*/. If one number is odd and the other
is even is even, then the two numbers have /*opposite parity*/.
** Rational Numbers
- A number $r$ is /*rational*/ if there exist integers $x$ and $y$ such that $y ≠ 0$ and
$r = x/y$.
** Divides
- An integer $x$ /*divides*/ an integer $y$ if and only if $x ≠ 0$ and $y = kx$, for some
integer $k$. The fact that $x$ divides $y$ is denoted $x | y$. If $x$ does not divide $y$, then
the fact is denoted $x ∤ y$.
** Prime and Composite Numbers
- An integer $n$ is /*prime*/ if and only if $n > 1$, and the only positive integers that divide
$n$ are $1$ and $n$.
- An integer $n$ is /*composite*/ if and only if $n > 1$, and there is an integer $m$ such that
$1 < m < n$ and $m$ divides $n$.
** Consecutive Integers
- Two integers are /*consecutive*/ if one of the numbers is equal to $1$ plus the other number.
Effectively $n = m + 1$.
** Proof by Contrapositive
- A /*proof by contrapositive*/ proves a conditional theorem of the form $p → c$ by showing that
the contrapositive $¬c → ¬p$ is true. In other words, $¬c$ is assumed to be true and $¬p$ is
proven as a result of $¬c$.
** Sets
*** Common Mathematical Sets
| Set | Symbol | Examples of Elements |
|--------------------|--------|---------------------------|
| Natural Numbers | | 0,1,2,3,... |
| Integers | | ...,-2,-1,0,1,2,... |
| Rational Numbers | | 0, 1/2, 5.23,-5/3, 7 |
| Irrational Numbers | | π, √2, √5/3, -4/√6 |
| Real Numbers | | 0, 1/2, 5.23, -5/3, π, √2 |
*** Subset
- If every element in $A$ is also an element of $B$, then $A$ is a /*subset*/ of $B$, denoted as $A ⊆ B$.
- If there is an element of $A$ that is not an element of $B$, then $A$ is not a subset of $B$,
denoted as $A ⊈ B$.
- If the universal set is $U$, then for every set $A$: $Ø ⊆ A ⊆ U$
- If $A ⊆ B$ and there is an element of $B$ that is not an element of $A$ (i.e. $A ≠ B$), then
$A$ is a /*proper subset*/ of $B$, denoted as $A ⊂ B$.
*** Power Set
- The /*power set*/ of a set $A$, denoted $P(A)$, is the set of all subsets of $A$. For example
if $A = {1,2,3}$, then: $P(A) = {Ø,{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}}$
**** Cardinality of a Power Set
- Let $A$ be a finite set of cardinality $n$. Then the cardinality of the power set of $A$ is
$2^n$, or $|P(A)| = 2^n$
*** Set Operations
**** Set Intersection
- Let $A$ and $B$ be sets. The $intersection$ of $A$ and $B$, denoted $A ∩ B$ and read "$A$
intersect $B$", is the set of all elements that are elements of both $A$ and $B$.
**** Set Union
- The /*union*/ of two sets, $A$ and $B$, denoted $A B$ and read "$A$ union $B$", is the set
of all elements that are elements of $A$ or $B$. The definition for union uses the inclusive
or, meaning that if an element is an element of both $A$ and $B$, then it also and element of
$A B$.
**** Set Difference
- The /*difference*/ between two sets $A$ and $B$, denoted $A - B$, is the set of elements that
are in $A$ but not in $B$.
- The difference operation is not commutative since it is not necessarily the case that $A - B = B - A$.
Consider that $3 - 2 ≠ 2 - 3$, same applies for the set difference operator.
**** Set Symmetric Difference
- The /*symmetric difference*/ between two sets, $A$ and $B$, denoted $A ⊕ B$, is the set of
elements that are a member of exactly one of $A$ and $B$, but not both. An alternate
definition of the symmetric difference operation is: $A ⊕ B = (A - B) (B - A)$
**** Set Complement
- The /*complement*/ of a set $A$, denoted $ ̅A$, is the set of all elements in $U$ (the
universal set) that are not elements of $A$. An alternate definition of $ ̅A$ is
$U - A$.
*** Summary of Set Operations
| Operation | Notation | Description |
|----------------------|----------|--------------------------------|
| Intersection | $A ∩ B$ | ${x: x ∈ A and x ∈ B}$ |
| Union | $A B$ | ${x: x ∈ A and x ∈ B or both}$ |
| Difference | $A - B$ | ${x: x ∈ A and x ∉ B}$ |
| Symmetric Difference | $A ⊕ B$ | ${x: x ∈ A - B or x ∈ B - A}$ |
| Complement | $ ̅A$ | ${x: x ∉ A}$ |
*** Set Identities
- A /*set identity*/ is an equation involving sets that is true regardless of the contents of the
sets in the expression.
- Set identities are similar to [[id:539a691a-ce6d-4711-84ba-57e74ed42f27][Laws of Propositional Logic]]
- The sets $U$ and $Ø$ correspond to the constants true (T) and false (F):
- $A ∈ Ø ↔ F$
- $A ∈ U ↔ T$
[[./assets/set-identities.png][Table of set identities]]
*** Cartesian Products
- An /*ordered pair*/ of items is written $(x,y)$
- The first /*entry*/ of the ordered pair $(x,y)$ is $x$ and the second entry is $y$
- The use of parentheses $()$ for an ordered pair indicates that the order of the entries is
significant, unlike sets which use curly braces ${}$
- Two ordered pairs $(x,y)$ and $(u,w)$ are equal if and only if $x = u$ and $y = w$
- For two sets, $A$ and $B$, the /*Cartesian product*/ of $A$ and $B$ denoted $A × B$, is the
set of all ordered pairs in which the first entry is in $A$ and the second entry is in $B$.
That is: $A × B = {(a,b): a ∈ A and b ∈ B}$
- Since the order of the elements in a pair is significant, $A × B$ will not be the same as
$B × A$, unless $A = B$, or either $A$ or $B$ is empty. If $A$ and $B$ are finite sets then
$|A × B| = |A| × |B|$
*** Strings
- A sequence of characters is called a /*string*/
- The set of characters used in a set of strings is called the /*alphabet*/ for the set of
strings
- The /*length*/ of a string is the number of characters in the string
- A /*binary string*/ is a string whose alphabet is {0,1}
- A /*bit*/ is a character in a binary string
- A binary string of length $n$ is also called an /*$n$-bit string*/
- The set of binary strings of length $n$ is denoted as ${0,1}^n$
- The /*empty string*/ is the unique string whose length is 0 and is usually denoted by the
symbol $λ$. Since ${0,1}^0$ is the set of all binary strings of length 0, ${0,1}^0 = {λ}$
- If $s$ and $t$ are two strings, then the /*concatenation*/ of $s$ and $t$ (denoted $st$) is
the string obtained by putting $s$ and $t$ together
- Concatenating any string $x$ with the empty string ($λ$) gives back: $x: xλ = x$
** Functions
_Definition of a function:_
#+begin_src typst
A function $f$ that maps elements of a set $X$ to elements of a set $Y$, is a subset of $X × Y$
such that for every $x ∈ X$, there is exactly one $y ∈ Y$ for which $(x,y) ∈ f$.
$f: X → Y$ is the notation to express the fact that $f$ is a function from $X$ to $Y$. The set
$X$ is called the _*domain*_ of $f$, and the set $Y$ is the _*target*_ of $f$. An alternate word
for target that is sometimes used is _*co-domain*_. The fact that $f$ maps $x$ to $y$
(or $(x,y) ∈ f$) can also be denoted as $f(x) = y$
#+end_src
- If $f$ maps an element of the domain to zero elements or more than one element of the target,
then $f$ is not /*well-defined*/.
- If $f$ is a function mapping $X$ to $Y$ and $X$ is a finite set, then the function $f$ can be
specified by listing the pairs $(x,y)$ in $f$. Alternatively, a function with a finite domain
can be expressed graphically as an arrow diagram.
- In an /*arrow diagram*/ for a function $f$, the elements of the domain $X$ are listed on the
left and the elements of the target $Y$ are listed on the right. There is an arrow diagram from
$x ∈ X$ to $y ∈ Y$ if and only if $(x,y) ∈ f$. Since $f$ is a function, each $x ∈ X$ has
exactly one $y ∈ Y$ such that $(x,y) ∈ f$, which means that in the arrow diagram for a
function, there is exactly one arrow pointing out of every element in the domain.
- See the following example arrow diagram: [[./assets/arrow-diagram.png]]
- For function $f: X → Y$, an element $y$ is in the /*range*/ of $f$ if and only if there is an
$x ∈ X$ such that $(x,y) ∈ f$.
- Expressed in set notation: Range of $f = {y: (x,y) ∈ f, for some x ∈ X}$
*** Function Equality
- Two functions, $f$ and $g$, are /*equal*/ if $f$ and $g$ have the same domain and target, and
$f(x) = g(x)$ for every element $x$ in the domain. The notation $f = g$ is used to denote the
fact that functions $f$ and $g$ are equal.
*** The Floor Function
- The /*floor function*/ maps a real number to the nearest integer in the downwards direction
- The floor function is denoted as: $floor(x) = ⌊x⌋$
*** The Ceiling Function
- The /*ceiling function*/ rounds a real number to the nearest integer in the upwards direction
- The ceiling function is denoted as: $ceiling(x) = ⌈x⌉$
*** Properties of Functions
- A function $f: X → Y$ is /*one-to-one*/ or /*injective*/ if $x_1 ≠ x_2$ implies that
$f(x_1) ≠ f(x_2)$. That is, $f$ maps different elements in $X$ to different elements in $Y$.
- A function $f: X → Y$ is /*onto*/ or /*surjective*/ if the range of $f$ is equal to the target
$Y$. That is, for every $y ∈ Y$, there is an $x ∈ X$ such that $f(x) = y$.
- A function is /*bijective*/ if it is both one-to-one and onto. A bijective function is called a /*bijection*/. A bijection is also called a /*one-to-one correspondence*/.
*** Composition of Functions
- The process of applying a function to the result of another function is called /*composition*/.
- Definition of /*function composition*/
#+begin_src typst
$f$ and $g$ are two function, where $f: X → Y$ and $g: Y → Z$. The composition of $g$ with
$f$, denoted $g ○ f$, is the function ($g ○ f): X → Z$, such that for all
$x ∈ X, (g ○ f)(x) = g(f(x))$
#+end_src
- Composition is /associative/
- The /*identity function*/ always maps a set onto itself and maps every element onto itself.
- The identity function on $A$, denoted $I_A: A → A$, is defined as $I_A(a) = a$, for all
$a ∈ A$
- If a function $f$ from $A$ to $B$ has an inverse, then $f$ composed with its inverse is the
indentity function. If $f(a) = b$, then $f^-1(b) = a$, and
$(f^-1 ○ f)(a) = f^-1(f(a)) = f^-1(b) = a$.
- Let $f: A → B$ be a bijection. Then $f^-1 ○ f = I_A$ and $f ○ f^-1 = I_B$
** Computation
*** Introduction to Algorithms
- An /*algorithm*/ is a step-by-step method for solving a problem. A description of an algorithm
specifies the input to the problem, the output to the problem, and the sequence of steps to be
followed to obtain the output from the input.
- A description of an algorithm usually includes
- A name for the algorithm
- A brief description of the task performed by the algorithm
- A description of the input
- A description of the output
- A sequence of steps to follow
- Algorithms are often described in /*pseudocode*/, which is a language between written English
and a computer language
- An important type of step in an algorithm is an /*assignment*/, in which a variable is given a
variable. The assignment operated is denoted by $:=$, for example to assign $x$ to $y$ you
would write it as: $x := y$.
- The output of an algorithm is specified by a /*return*/ statement.
- For example, the statement $Return(x)$ would return the value of $x$ as the output of the
algorithm.
- A return statement in the middle of an algorithm causes the execution of the algorithm to
stop at that point and return the indicated value
**** The if-statement and the if-else-statement
- An /*if-statement*/ tests a condition, and executes one or more instructions if the condition
evaluates to true. In a single line if-statement, a conditon and instruction appear on the
same line.
- An /*if-else-statement*/ tests a condition, executes one or more instructions if the condition
evaluates to true, and executes a different set of instructions in the condition evaluates to
false.
**** The for-loop
- In a /*for-loop*/, a block of instructions is executed a fixed number of times as specified in
the first line of the for-loop, which defines an /*index*/, a starting value for the index,
and a final value for the index.
- Each repetition of the block of instructions inside the for-loop is called an /*iteration*/.
- The index is initially assigned a value equal to the starting value, and is incremented just
before the next iteration begins.
- The final iteration of the for-loop happens when the index reaches the final value.
**** The while-loop
- A /*while-loop*/ iterates an unknown number of times, ending when a certain condition becomes
false.
*** Asymptotic Growth of Functions
- The /*asymptotic growth*/ of the function $f$ is a measure of how fast the output $f(n)$ grows
as the input $n$ grows.
- Classification of functions using Oh, $Ω$, and $Θ$ notation (called /*asymptotic notation*/)
provides a way to concisely characterize the asymptotic growth of a function.
**** O-notation
- The notation $f = O(g)$ is read "$f$ is /*Oh of*/ $g$". $f = O(g)$ essentially means that the
function $f(n)$ is less than or equal to $g(n)$, if constant factors are omitted and small
values for $n$ are ignored.
- The $O$ notation serves as a rough upper bound for functions (disregarding constants and
small input values)
- In the expressions $7n^3$ and $5n^2$, the $7$ and the $5$ are called /*constant factors*/
because the values of $7$ and $5$ do not depend on the variable $n$.
- If $f$ is $O(g)$, then there is a positive number $c$ such that when $f(n)$ and $c × g(n)$ are
graphed, the graph of $c × g(n)$ will eventually cross $f(n)$ and remain higher than $f(n)$
as $n$ gets large.
- Definition: /Oh notation/
#+begin_src typst
Let $f$ and $g$ be functions from $^+$ to $^>=$. Then $f = O(g)$ if there are positive real
numbers $c$ and $n_0$ such that for any $n ∈ ^+$ such that $n >= n_0$: $f(n) <= c × g(n)$.
#+end_src
- The constants $c$ and $n_0$ in the definition of Oh-notation are said to be a /*witness*/ to
the fact that $f = O(g)$.
**** Ω Notation
- The $Ω$ notation provides a lower bound on the growth of a function
- $Ω$ notation definition:
#+begin_src typst
Let $f$ and $g$ be functions from $^+$ to $^>=$. Then $f = Ω(g)$ if there are positive real
numbers $c$ and $n_0$ such that for any $n ∈ ^+$ such that for $n >= n_0$,
$f(n) >= c × g(n)$
The notation $f = Ω(g)$ is read "$f$ is _*Omega*_ of $g$".
#+end_src
- Relationship between Oh-notation and $Ω$-notation:
#+begin_src typst
Let $f$ and $g$ be functions from $^+$ to $^>=$. Then $f = Ω(g)$ if and only if $g = O(f)$
#+end_src
**** 𝛩 notation and polynomials
- The $𝛩$ notation indicates that two functions have the same rate of growth
- $𝛩$-notation definition:
#+begin_src typst
Let $f$ and $g$ be functions from $^+$ to $^>=$.
$f = 𝛩(g)$ if $f = O(g)$ and $f = Ω(g)$
The notation $f = 𝛩(g)$ is read "$f$ is *_Theta of_* $g(n)$"
#+end_src
- If $f = 𝛩(g)$, then $f$ is said to be /*order of*/ $g$.
- /*Lower order*/ terms are those that can be removed from $f$ that does not change the /order/
of $f$.
**** Asymptotic growth of polynomials
#+begin_src typst
Let $p(n)$ be a degree-$k$ polynomial of the form:
$p(n) = a_kn^k + ... + a_1n + a_0$
in which $a_k > 0$. Then $p(n)$ is $𝛩(n^k)$
#+end_src
**** Asymptotic growth of logarithm functions with different bases
Let $a$ and $b$ be two real numbers greater than $1$, then $log_a(n) = 𝛩(log_b(n))$
**** Growth rate of common functions in analysis of algorithms
- A function that does not depend on $n$ at all is called a /*constant function*/. $f(n) = 17$
is an example of a constant function.
- Any constant function is $𝛩(1)$.
- If a function $f(n)$ is $𝛩(n)$, we say that $f(n)$ is a =linear= function.
- A function $f(n)$ is said to be /*polynomial*/ if $f(n)$ is $𝛩(n^k)$ for some positive real
number $k$.
**** Common functions in algorithmic complexity.
The following table of functions are given in increasing order of complexity, with the $m$
in the third from the bottom being any $m > 3$:
[[./assets/common-funcs-algo-complexity.png][Table here]]
**** Rules about asymptotic growth
[[./assets/rules-asymptotic-growth-of-functions.png][See here]]
*** Analysis of algorithms
- The amount of resources used by an algorithm is referred to as the algorithm's /*computational complexity*/.
- The primary resources to optimize are the time the algorithm requires to run
(/*time complexity*/) and the amount of memory used (/*space complexity*/).
- The /*time complexity*/ of an algorithm is defined by a function $f: ^+ → ^+$ such that $f(n)$
is the maximum number of atomic operations performed by the algorithm on any input of
size $n$. $^+$ is the set of positive integers.
- The /*asymptotic time complexity*/ of an algorithm is the rate of asymptotic growth of the
algorithm's time complexity function $f(n)$.
**** Worst-case complexity
- The /*worst-case analysis*/ of an algorithm evaluates the time complexity of the algorithm on
the input of a particular size that takes the longest time.
- The /*worst-case*/ time complexity function $f(n)$ is defined to be the maximum number of
atomic operations the algorithm requires, where the maximum is taken over all inputs of size
$n$.
- When proving an /*upper bound*/ on the worst-case complexity of an algorithm (using
$O$-notation), the upper bound must apply for every input of size $n$.
- When proving a /*lower bound*/ for the worst-case complexity of an algorithm (using
$Ω$-notation), the lower bound need only apply for at least one possible input of size $n$.
- /*Average-case analysis*/ evaluates the time complexity of an algorithm by determining the
average running time of the algorithm on a random input.