~williamvds/university

f6ec1e9e0ada9834d129f9c6fc69c68d2baa8bc8 — williamvds 6 years ago c70adf8
notes: fixes
3 files changed, 64 insertions(+), 53 deletions(-)

M ace/lectures.md
M aim/lectures.md
M lac/lectures.md
M ace/lectures.md => ace/lectures.md +12 -6
@@ 6,7 6,7 @@ InsertionSort(A)
  <invariant: subarray A[1..j-1] is sorted>
    key = A[j] 
    i = j – 1  
    while(i > 0 and A[i] > key)          
    while(i > 0 and A[i] > key)
      <invariant: all elements A[i+1..j] are >= key>
      A[i + 1] = A[i]
      i--


@@ 40,6 40,13 @@ trivially sorted
  3. __Conquer__: combine solutions for both subsets into solution for input data

## Merge-sort
```
mergesort(xs):
  if xs.length <= 1: return xs
  left, right = divide(xs)
  merge( mergesort(left), mergesort(right) )
```

- Eg, sorting an input sequence `S` with `n` elements
1. __Divide__: Partition input into two sequences `S₁` and `S₂` both of size
approx. n/2


@@ 270,9 277,7 @@ exception
- Throw `FullQueueException` if full on `enqueue()`

### Linked List implementation
- New arrivals placed at head
- Remove from head, insert at tail
- First element in queue stored at head of list
- Store size as attribute, update upon insertion/removal
- Space complexity 𝑂(n) - one list entry for each element
- Time complexity 𝑂(1) operations


@@ 289,6 294,7 @@ exception
- __Cons__
  - Can be scattered around memory = poor cache usage
  - Has to store _next_ reference = more memory usage
  - Have to walk the list to reach a desired element

# Trees
- An abstract model of a hierarchical structure


@@ 375,7 381,7 @@ nodes, and skipping index 0
- Nodes must either have two or no children
- A tree consisting of only a root node is a proper binary tree

### Perfect binary tries
### Perfect binary trees
- All leaves are at the same depth - hence all levels are full
- `n` is the number of nodes in the tree
- `d` is the depth of the tree


@@ 387,7 393,7 @@ nodes, and skipping index 0
- __Nodes at depth__ `d+1`: `2^(d+1) -1`
- __Height__: `log₂(n+1)-1`
  - Θ(log(n))
- __Total nodes with height__ `h`: `2^(h-1) -1`
- __Total nodes with height__ `h`: `2^(h+1) -1`
  - `h = 0`: `2^1 -1 = 1` node (root)
  - Assuming tree of height `h-1` has `2^h -1` nodes, a tree with another level
(total `n`) has another `2^h` nodes


@@ 481,7 487,7 @@ throwing exception
  - `c` is constant, so `T(n)` is 𝑂(n + k²), so 𝑂(n²)
  - Amortised time is 𝑂(n)

### Incremental example
### Geometric example
- Array starts with size 3
- Example sequence of _push_ operations: `1, 1, 1, 3+1, 1, 1, 1, 6+1, 1, 1, 1,
1, 1, 1, 12+1, ...`

M aim/lectures.md => aim/lectures.md +24 -24
@@ 445,9 445,9 @@ continue with next best neighbour
- __Neighbourhood definition__: Eg, attainable by single bit flip
- __Memory__: Associate tabu status (boolean) with each variable of in problem
  - tabu = changed in last `T` steps, where `T` is tabu tenure
  - For each variable `x_i` store number of the search step when it was last
changed (`t_i`).
  - tabu = `c - t_i < T`, where c is current search step number
  - For each variable `xᵢ` store number of the search step when it was last
changed (`tᵢ`).
  - tabu = `c - tᵢ < T`, where `c` is current search step number

### Considerations & improvements
- __Tabu tenure__ choice is critical for performance:


@@ 490,13 490,13 @@ same time/iteration
- Gradually decrease rate at which worsening moves are accepted
1. Generate an initial _temperature_
2. Perturb current solution
3. Accept if better or with Boltzman probability - e^(delta/temp)
3. Accept if better or with Boltzman probability - _e_^(delta/temp)
  - Lower temperature means fewer worsening accepted
4. _Cool_ temperature according to _cooling schedule_

- __Geometric Cooling__
  - 𝛼: Cooling rate - fixed value less than 1
  - temp = 𝛼*temp
  - α: Cooling rate - fixed value less than 1
  - temp = α*temp
- __Lundy & Mees__
  - Parameter β
  - temp = temp/(1+ β*temp)


@@ 524,7 524,6 @@ a certain number iterations ago
    - Parameters: _rain up speed_, _water level_
    - Tighten threshold upon each accepted solution
  - Flex Deluge
    - 
- __Adaptive__
  - Record to Record Travel (RRT)
    - Fixed _deviation_


@@ 579,9 578,9 @@ precisely one sample from each subgrid
- `i = [1, m]`: Number of machines
- `j = [1, n]`: Number of jobs
- `(i,j)`: A processing step (operation) of job `j` on machine `i`
- `p_ij`: Processing time of job `j` on machine `i`
- `d_j`: Due date - time job `j` must be completed by
- `w_j`: Weight - importance of job `j` relative to other ones
- `pᵢⱼ`: Processing time of job `j` on machine `i`
- `dⱼ`: Due date - time job `j` must be completed by
- `wᵢⱼ`: Weight - importance of job `j` relative to other ones

## Notation: α | β | γ
- α: Machine characteristics


@@ 600,17 599,17 @@ machines
  - Machines have different speeds for different jobs

### β examples
- Release date `r_j`: earliest time at which job `j` can start being processed
- Sequence dependent startup times `s_jk`: setup time between `j` and `k`
- Release date `rⱼ`: earliest time at which job `j` can start being processed
- Sequence dependent startup times `sⱼₖ`: setup time between `j` and `k`
- Breakdowns `brkdwn`: machines are not continuously available
- Permutation `prmu`: eg order of queue processing (FIFO)

### γ examples
- Completion time `C_ij`: of job `j` on machine `i`
- Time when job exits system `C_j`
- Lateness of `j` `L_j = C_j - d_j`
- Tardiness `T_j = max(C_j - d_j, 0)`
- Unit penalty `U_j = 1 if C_j > d_j otherwise 0`
- Completion time `Cᵢⱼ`: of job `j` on machine `i`
- Time when job exits system `Cⱼ`
- Lateness of `j` `Lⱼ = Cⱼ - dⱼ`
- Tardiness `Tⱼ = max(Cⱼ - dⱼ, 0)`
- Unit penalty `Uⱼ = 1 if Cⱼ > dⱼ otherwise 0`

# Evolutionary algorithms



@@ 628,7 627,8 @@ machines

- __Chromosome__: A candidate solution (aka individual)
- __Population__: A set of _individuals_ currently 'alive' - being considered
- __Evolution__: Each population is are evolved from one generation ( _iteration_ ) to another depending on their _fitness_ 
- __Evolution__: Each population is are evolved from one generation ( _iteration_ )
to another depending on their _fitness_ 
  - Fitness is how close it is to the optimal solution, depends on objective
function value
- Ideally the last generation will contain the best solution(s)


@@ 851,9 851,9 @@ with highest score
    1. Individual performance
    - Performance when combined with other heuristics
    - Elapsed time since being applied
  - Fₜ(hⱼ) = 𝛼ₜf₁(hⱼ) + 𝛽ₜf₂(h_k, hⱼ) + 𝛾ₜf₃(hⱼ)
  - Fₜ(hⱼ) = αₜf₁(hⱼ) + βₜf₂(h_k, hⱼ) + γₜf₃(hⱼ)
  - fₙ is the respective performance metric
  - Parameters 𝛼, 𝛽, and 𝛾 control importance of each metric [0,1]
  - Parameters alpha , β, and γ control importance of each metric [0,1]

## Misconceptions (opinionated)
- Hyperheuristics...


@@ 983,8 983,8 @@ represented
## Compared to classical (aka crisp) sets
- Elements of the universal set `X` are defined to be or not to be members of
a set `A` by a characteristics function
- For a given set `A`, this function assigns value `mu_A(x)` to every `x` in `X`
- `mu_A(x): X -> {0,1}`, 0 iff `x` is in `A`, 1 otherwise
- For a given set `A`, this function assigns value `μ_A(x)` to every `x` in `X`
- `μ_A(x): X -> {0,1}`, 0 iff `x` is in `A`, 1 otherwise
- Can create a diagram visualising which ranges map to 0, and those which map
to 1
- Eg, defining tall people - set an arbitrary lower limit of height, above which


@@ 993,8 993,8 @@ people are considered tall
_degree_ of height

## Notation
- `A = mu_1/x1 + mu_2/x2 + ... + mu_n/x_n`
- or `A =  Σ_(i=0,n) mu_i/x_i`
- `A = μ₁/x₁ + μ₂/x₂ + ... + μₙ/xₙ`
- or `A =  Σ_(i=1,n) μᵢ/xᵢ`

## Meaning of fuzzy grades
- Fuzzy memberships are not probabilities - eg, not applicable to height

M lac/lectures.md => lac/lectures.md +28 -23
@@ 197,21 197,21 @@ final states

## Definition
1. ∅ is a regex
  - Empty set - no accepted words
    - Empty set - no accepted words
-  ϵ is a regex
  - Only accept the empty string
    - Only accept the empty string
-  __x__ is a regex ∀ __x__ ∈ Σ
  - Accept single symbols from the alphabet
    - Accept single symbols from the alphabet
-  E+F is a regex if E and F are regexes
  - __Alternation__
  - Accept either E or F
    - __Alternation__
    - Accept either E or F
-  EF is a regex if E and F are regexes
  - __Juxtaposition/concatenation__
    - __Juxtaposition/concatenation__
-  E^*  is a regex if E is a regex
  - __Kleene star__
  - Accept all possible combinations of the full strings of set E
    - __Kleene star__
    - Accept all possible combinations of the full strings of set E
-  (E) is a regex if E is a regex
  - Allows stronger binding
    - Allows stronger binding

- Operator binding is stronger further down the definition
  - (E) > E^* > EF > E+F


@@ 238,12 238,17 @@ simple method to convert to a NFAs
- The diagrams for N(E) and N(F) are merged into one - draw a box around both

### N(EF)
1. Identify penultimate states in E (ie. ones leading to an accepting state)
1. Identify penultimate states in N(E) (ie. ones leading to an accepting state)
2. Connect each of these to each of the initial states of N(F)
3. If there is an initial state in N(E) that is also accepting, keep the initial
states in N(F), otherwise remove them

# 𝒫  vs 𝒩 𝒫
### N(E^*)
1. Identify penultimate states in N(E) (ie. ones leading to an accepting state)
2. Connect each of these to each of the initial states of N(E)
3. Add an initial and accepting state

# 𝒫  vs 𝒩𝒫
- __Motivations__
  - __Efficient__ exact algorithms have runtimes of low-order power laws
  - __Inefficient__ complete/exact algorithms have runtimes have exponential


@@ 256,12 261,12 @@ Turing Machine in polynomial time p(n)
state qₖ and any symbol that can occur when the machine is in that state
  - At most one choice for the next move

## 𝒩 𝒫
## 𝒩𝒫
- The set of problem classes that can be solved using a
__non__deterministic Turing Machine in polynomial time
__nondeterministic__ Turing Machine in polynomial time
- A subset of __𝒫__
- __Turing Machine definition__
  - A language L is in the class 𝒩 𝒫 if there is a deterministic Turing Machine
  - A language L is in the class 𝒩𝒫 if there is a deterministic Turing Machine
M and a polynomial function f such that...
    - Running M on a tape with two inputs w and v (separated by a blank), it
  always terminates in steps less than f(|w|)


@@ 271,7 276,7 @@ M and a polynomial function f such that...
  - If M gives a positive answer when run on w and v, v is a _certificate/proof_
w is in L
    - If L is a problem, and w an instance, v is a solution for w
- Many common decision problems are 'obviously' __𝒩 𝒫__
- Many common decision problems are 'obviously' __𝒩𝒫__
- eg SUBSET-SUM: Find a subset of a set of values that sum to a particular value
  - Verification is 𝑂(n) - sum the subset, compare to value
  - Brute force algorithm 𝑂(2ⁿ) - check sum of each subset of S


@@ 303,17 308,17 @@ itself can solve the problem
time
  - So conversions are restricted to those that can be done in polynomial time

### 𝒩 𝒫-hardness
- A problem class to which _any_ 𝒩 𝒫 problem can be reduced to
### 𝒩𝒫-hardness
- A problem class to which _any_ 𝒩𝒫 problem can be reduced to
- Such a problem class is 'as bad as it gets'
  - If such a problem class turns out to be in 𝒫 then 𝒫=𝒩 𝒫 
- Usually done by showing polynomial-time reduction from some known 𝒩 𝒫-complete
  - If such a problem class turns out to be in 𝒫 then 𝒫=𝒩𝒫 
- Usually done by showing polynomial-time reduction from some known 𝒩𝒫-complete
problem
- Eg Boolean satisfiability

### 𝒩 𝒫-completeness
- Problem class X is 𝒩 𝒫-complete if:
  - X is in 𝒩 𝒫
### 𝒩𝒫-completeness
- Problem class X is 𝒩𝒫-complete if:
  - X is in 𝒩𝒫
    - All instances of X can be solved in nondeterministic polynomial time
    - Membership of N is usually demonstrated directly (and fairly easily)
  - X is 𝒩 𝒫-hard
  - X is 𝒩𝒫-hard