Skip to content

Commit b5d82f6

Browse files
committed
Checked over all of algorithms file
1 parent 4f5d387 commit b5d82f6

File tree

3 files changed

+69
-72
lines changed

3 files changed

+69
-72
lines changed

docs/algorithms.md

Lines changed: 60 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ icon: material/code-tags
44

55
# Algorithms
66

7-
!!! danger
8-
9-
This is a work in progress. Some information may be incorrect or outdated
10-
117
---
128

139

@@ -340,7 +336,7 @@ There are problems documented everywhere in this site. This location will detail
340336

341337
[There are $\frac{!(n-1)}{2}$ possible routes](https://youtu.be/GiDsjIBOVoA?t=194) for a [complete graph](graphs.md#complete-graphs) input. The division of two is to eliminate the other half of paths that go in the reverse order
342338

343-
> The number of different Hamiltonian cycles in a complete undirected graph on n vertices is $\frac{(n-1)!}{2}$ and in a complete directed graph on n vertices is $(n- 1)!$. These counts assume that cycles that are the same apart from their starting point are not counted separately. ([source](https://en.wikipedia.org/wiki/Hamiltonian_path#Properties))
339+
> The number of different Hamiltonian cycles in a complete undirected graph on n vertices is $\frac{(n-1)!}{2}$ and in a complete directed graph on n vertices is $(n- 1)!$. These counts assume that cycles that are the same apart from their starting point are not counted separately. ([source](https://en.wikipedia.org/wiki/Hamiltonian_path#Properties))
344340
345341

346342
!!! note "Game"
@@ -401,12 +397,13 @@ Swaps are counted with: $O(n)$
401397

402398
### Quick Sort
403399

404-
Quick Sort uses a recursive divide and conquer method.
400+
Quick Sort uses a [recursive](#recursion) [divide and conquer](#divide-and-conquer) method.
405401

406402
<img src="images/Sorting_quicksort_anim.gif" alt="Sorting_quicksort_anim">
407403
![Quicksort stationary pivot](https://upload.wikimedia.org/wikipedia/commons/f/fe/Quicksort.gif)
408404

409405
Order:
406+
410407
1. Select random pivot (usually last)
411408
2. Check every other element in the array
412409
1. All values less than pivot are on its left
@@ -415,7 +412,7 @@ Order:
415412
3. Do quick-sort on items left of original quick-sort
416413
4. Do quick-sort on items right of original quick-sort
417414

418-
Worst case:
415+
Worst case (*consider how the pivot and/or the input would cause this*):
419416

420417
$$O(n^2)$$
421418

@@ -433,22 +430,27 @@ $$O(n)$$
433430

434431
A commonly used [divide and conquer](#divide-and-conquer) sorting algorithm. In fact it's probably one of the best examples of divide and conquer there is. The fundamental procedure of merge sort is to split apart the input (dividing) and solve each of those parts individually (conquoring) and then building the solution back together. This is a key difference between divide and conquer and [decrease and conquer](#decrease-and-conquer) as the input is being *divided* into sub-problems that are **all** solved, instead of *decreasing* the problem by discarding parts that don't need to be solved.
435432

433+
Merge sort runs in $O(n \, \log n)$ at worst case. Although this is considered as one of the fastest sorting algorithms, there are alternitives outside the study design that can run in $O(n+k)$ and $O(nk)$ (radix and counting sort) with fancy space tradeoffs.
434+
436435
## Searching
437436

438437
### linear Search
439438

440439
Most simple, checks elements left to right until the item is found.
441440

442-
Average case:
441+
Worst case:
443442

444-
$$\Theta\left(\frac{n}{2}\right)$$
443+
$$O(n)$$
444+
445+
It's not in the study design, but an average case of $\Theta\left(\frac{n}{2}\right)$ and a best case of $\Omega(1)$ are quite intuitive
445446

446447
### Binary Search
447448

448-
- Recursive divide and conquer.
449-
- **Must be sorted**
449+
- [Recursive](#recursion) [divide and conquer](#divide-and-conquer).
450+
- **Input must be sorted**
450451

451452
Order:
453+
452454
1. Select item from middle of array
453455
1. If matches: halt
454456
2. if item < what your looking for: search right side
@@ -458,7 +460,7 @@ Worst case:
458460

459461
$$O(\log_2 n) \implies O(\log n)$$
460462

461-
*Note that the number of searches in worst case is $\lfloor \log_2(n)\rfloor +1$*
463+
*Note that the number of searches in worst case is $\lfloor \log_2(n)\rfloor +1$*. This is still pretty good. If you had to binary search all the atoms in the uinverse you would only have to use 267 operations
462464

463465

464466
## Types of algorithms
@@ -470,19 +472,19 @@ $$O(\log_2 n) \implies O(\log n)$$
470472
- Use [Divide and Conquer](#divide-and-conquer) when you **don't have overlapping sub problems**
471473
- Use [Decrease and Conquer](#decrease-and-conquer) when you can **discard/ignore parts of the input** entirely
472474
- Use [Dynamic Programming](#dynamic-programming) when you **do have overlapping sub problems**
473-
- Use [Backtracking](#backtracking) when you can solve parts of the problem along the way and re-trace your steps when you make a mistake
474-
- Use [Greedy](#greedy) when you see an optimisation that involves disregarding future consequences (which shoudn't normally exist in greedy implimentations)
475+
- Use [Backtracking](#backtracking) when you can solve parts of the problem along the way and **re-trace your steps** when you make a mistake
476+
- Use [Greedy](#greedy) when you see an optimisation that involves **disregarding future consequences** (which shoudn't normally exist in greedy implimentations)
475477
- Use [Brute Force](#brute-force) when you can't do it any other way.
476478

477-
Both iterative and recursive algorithm design patterns in general are also part of the study design.
479+
Both iterative and recursive algorithm design patterns in general are also part of the study design.
478480

479-
Both [backtracking](#backtracking) and [greedy](#greedy) algorithms types are debated to be design patterns or not. For the sake of VCE Algorithimics, the study design classes both backtracking and greedy classifications as design patterns in key knowledge and key skill markers:
481+
Both [backtracking](#backtracking) and [greedy](#greedy) algorithms types are debated to be design patterns or not. For the sake of VCE Algorithimics, the study design classes both backtracking and greedy classifications as design patterns in key knowledge and key skill markers:
480482

481-
> - Apply the divide and conquer, dynamic programming and backtracking design patterns to design algorithms and recognise their usage within given algorithms
483+
> - Apply the divide and conquer, dynamic programming and backtracking design patterns to design algorithms and recognise their usage within given algorithms
482484
483-
> - Characteristics and suitability of the brute-force search and greedy algorithm design patterns
485+
> - Characteristics and suitability of the brute-force search and greedy algorithm design patterns
484486
485-
The study design also doesn't explicityly list '*Decrease and Conquer*' as a design pattern, but it does list both iterative and recursive patterns which can be applicable to decrease and conquer.
487+
The study design also doesn't explicityly list '*Decrease and Conquer*' as a design pattern, but it does list both iterative and recursive patterns which can be applicable to decrease and conquer.
486488

487489
#### Brute Force
488490

@@ -547,7 +549,7 @@ Examples:
547549

548550
!!! info
549551

550-
In general, DP solutions are used to maximise or minimise. Knapsack or coin change.
552+
In general, DP solutions are used to maximise or minimise. Like Knapsack or [coin change](#coin-change-algorithm).
551553

552554
They store previous answers to stop the repetition of overlapping sub-problems
553555

@@ -590,7 +592,7 @@ For example (TSP):
590592

591593
#### Evolutions
592594

593-
Algorithm will repeatedly evaluate all the tours in the dish
595+
Algorithm will repeatedly evaluate all the tours in the "dish"
594596
- throw out the longer tours
595597
- replace them with copies of the better tours
596598
- each copy is slightly different than the tour it was copied from
@@ -648,7 +650,6 @@ When stuck at:
648650
- One can prove: If temperature decreases slowly enough, then simulated annealing search will find a global optimum with probability approaching one, which means you are certain of your solution. However, this usually takes impractically long.
649651

650652
<img src="images/Hill_Climbing_with_Simulated_Annealing.gif" alt="Hill_Climbing_with_Simulated_Annealing">
651-
<sup>**Gif^^**</sup>
652653

653654
!!! info
654655

@@ -672,13 +673,14 @@ A case to terminate a recursive function:
672673

673674
```js
674675
function factorial(x)
675-
// Base case (x == 0) or x <= 0
676-
if x == 0:
676+
if x == 0: // (1)
677677
return 1
678678
else:
679679
return x*factorial(x-1)
680680
```
681681

682+
1. The base case triggers when (x == 0) or (x <= 0)
683+
682684

683685

684686
## Math
@@ -703,13 +705,13 @@ $${n!=n(n-1)!\quad {\text{for}}\quad n>0,}$$
703705

704706
<br>
705707

706-
$$T(\textcolor{red}{n})=\textcolor{orange}{a}T\left(\frac{n}{\textcolor{yellow}{b}}\right)+\textcolor{green}{f(n^k)}$$
708+
$$T(\textcolor{red}{n})=\textcolor{orange}{a}T\left(\frac{n}{\textcolor{purple}{b}}\right)+\textcolor{green}{f(n^k)}$$
707709

708710
Where:
709711

710712
- $\textcolor{red}{n}$ is the original size of the problem
711713
- $\textcolor{orange}{a}$ is the number of subproblems in the recursion (how many times called in the function)
712-
- $\textcolor{yellow}{b}$ is the number of dividing of input data that is done
714+
- $\textcolor{purple}{b}$ is the number of dividing of input data that is done
713715
- $\textcolor{green}{f(n^k)}$ is the cost of the work done outside the recursive call
714716

715717
!!! note
@@ -720,7 +722,7 @@ Where:
720722

721723
!!! warning
722724

723-
The Master theorem **cannot** be used on recursive algorithms where the **sub-problems overlap**, or decrease and conquor.
725+
The Master theorem **cannot** be used on recursive algorithms where the **sub-problems overlap**, or decrease and conquor.
724726

725727
Only recursive divide and conquor when the above applies
726728

@@ -764,7 +766,7 @@ $${PR(A)={\frac {PR(B)}{2}}+{\frac {PR(C)}{1}}+{\frac {PR(D)}{3}}}$$
764766
765767
!!! info
766768
767-
[https://youtu.be/qxEkY8OScYY](https://youtu.be/qxEkY8OScYY)
769+
<iframe width="560" height="315" src="https://www.youtube.com/embed/qxEkY8OScYY?si=rg-kzamjXyxP05DI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
768770
769771
##### Damping factor
770772
@@ -821,8 +823,6 @@ So, when proving by induction, do the following:
821823
822824
---
823825
824-
From seminar
825-
826826
Consider a **Loop invariant**. Which is some condition that is true before and after each loop. Then use that to build on a True solution / proof
827827
828828
Examples:
@@ -888,7 +888,7 @@ He was wrong, see Gödel's Incompleteness Theorem (Not in 2023 course design)
888888
889889
The main goal of Hilbert's program was to provide secure foundations for all mathematics. In particular this should include:
890890

891-
- A formulation of all mathematics; in other words all mathematical statements should be written in a precise [formal language](https://en.wikipedia.org/wiki/Formal_language "Formal language"), and manipulated according to well defined rules.
891+
- A formulation of all mathematics; in other words all mathematical statements should be written in a precise [formal language](https://en.wikipedia.org/wiki/Formal_language "Formal language"), and manipulated according to well defined rules.
892892
- Completeness: a proof that all true mathematical statements can be proved in the formalism.
893893
- Consistency: a proof that no contradiction can be obtained in the formalism of mathematics. This consistency proof should preferably use only "finitistic" reasoning about finite mathematical objects.
894894
- Conservation: a proof that any result about "real objects" obtained using reasoning about "ideal objects" (such as uncountable sets) can be proved without using ideal objects.
@@ -920,6 +920,10 @@ An equivalent of the [Turing machine](computer-science.md#turing-machine) invent
920920
921921
#### Halting problem
922922
923+
!!! important
924+
925+
In the current 2024 study design
926+
923927
Machine $H$ determines if the input $I$ (program and program input) will halt or not.
924928
925929
<img src="images/Pasted image 20220910162947.png" alt="Pasted image 20220910162947" width="200">
@@ -1002,9 +1006,7 @@ A non linear sequence of numbers such as `1,2,4,8,16,31,64`
10021006
10031007
#### Solving
10041008
1005-
!!! info
1006-
1007-
[Telescoping vs Iteration](https://youtu.be/lPCS2FFyqNA)
1009+
<iframe width="560" height="315" src="https://www.youtube.com/embed/lPCS2FFyqNA?si=Dh_64OIolEAK8qBI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
10081010
10091011
### Mathematical Analysis
10101012
@@ -1046,7 +1048,7 @@ Literally "a problem that can be handled"
10461048
- Including $n \log n$
10471049
10481050
Examples:
1049-
- Merge-sort
1051+
- [Merge-sort](#merge-sort)
10501052
10511053
##### Intractable problems
10521054
@@ -1223,7 +1225,6 @@ Given lower bound $a$ and upper bound $b$, calculate the mid (average) value $c$
12231225

12241226
### Binomials
12251227

1226-
Yeah this took you a while to realise. Pascals triangle is a seating plan for combinations.
12271228

12281229
```python title="Pascal's triangle in Python"
12291230
from math import comb
@@ -1268,6 +1269,7 @@ A game where a computer (A) and a person (B have to convince the interrogator (C
12681269
<img src="images/Pasted image 20220912092432.png" alt="Pasted image 20220912092432" width="300">
12691270
12701271
This test asks:
1272+
12711273
- Can machines think?
12721274
- Can a machine imitate the responses of a human?
12731275
- Can a machine pass a Turing Test?
@@ -1390,7 +1392,6 @@ Outputs $[-1, 1]$
13901392

13911393
#### Perceptron
13921394

1393-
- Kind of like the evaluation function for the Wordle Solver
13941395

13951396
Essentially, it takes several inputs and multiplies them by their bias to be matched against a threshold or bias. The result of the bias comparison is then the resultant binary output. Which is: True or false, Yes or No, `0`, `1` etc
13961397

@@ -1478,43 +1479,39 @@ The inputs are only provided to the network, and it must learn on its own (self
14781479
### Conditions
14791480

14801481
A condition must have the following properties:
1482+
14811483
- It must be a logical statement, i.e. one that can either be true or false, and
14821484
- It must be possible to know at the time the algorithm is being followed whether the statement is true or false.
14831485

14841486
### Abstractions
14851487

14861488
Changing real items, into abstracted representations (E.g. Intersections -> nodes on a graph).
14871489

1488-
#### Signifiers
1489-
1490-
1491-
1492-
14931490
### Coin Change algorithm
14941491

14951492
```python title="DP Coin Change in python"
14961493
def change(change, denominations):
1497-
    '''Outputs number of coins required to complete give the `change`'''
1498-
    # solution/dp array
1499-
    y = [1]
1500-
    for runninc in range(2, change+1):
1501-
        # Add minimum solution to y
1502-
        y.append(runninc)
1503-
        for coin in denominations:
1504-
            # The new amount of change to work with
1505-
            newdif = runninc-coin
1506-
            if newdif > 0:
1507-
                # There's still some change left
1508-
                if y[newdif-1]+1 < runninc:
1509-
                    # If the coins needed for the new change is better then the minimum
1510-
                    # The +1 implies we have already used a `coin`
1511-
                    y[runninc-1] = y[newdif-1]+1
1512-
            elif newdif == 0:
1513-
                # This has solved this iteration of change calculation
1514-
                y[runninc-1] = 1
1515-
    # Return last value
1516-
    print(y)
1517-
    return y[-1]
1494+
'''Outputs number of coins required to complete give the `change`'''
1495+
# solution/dp array
1496+
y = [1]
1497+
for runninc in range(2, change+1):
1498+
# Add minimum solution to y
1499+
y.append(runninc)
1500+
for coin in denominations:
1501+
# The new amount of change to work with
1502+
newdif = runninc-coin
1503+
if newdif > 0:
1504+
# There's still some change left
1505+
if y[newdif-1]+1 < runninc:
1506+
# If the coins needed for the new change is better then the minimum
1507+
# The +1 implies we have already used a `coin`
1508+
y[runninc-1] = y[newdif-1]+1
1509+
elif newdif == 0:
1510+
# This has solved this iteration of change calculation
1511+
y[runninc-1] = 1
1512+
# Return last value
1513+
print(y)
1514+
return y[-1]
15181515
15191516
15201517
# make sure this has a 1 coin denomination

docs/computer-science.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ A [Turing machine](#turing-machine) that follows fixed rules. **A natural or rea
408408

409409
Can solve NP problems?
410410

411-
A theoretical [Turing machine](#turing-machine) whose governing rules specify more than one possible action when in some given situations. That is, an NTM's next state is _not_ completely determined by its action and the current symbol it sees, unlike a [Deterministic Turing machine](#deterministic-turing-machine)
411+
A theoretical [Turing machine](#turing-machine) whose governing rules specify more than one possible action when in some given situations. That is, an NTM's next state is _not_ completely determined by its action and the current symbol it sees, unlike a [Deterministic Turing machine](#deterministic-turing-machine)
412412

413413
### Universal Turing Machine
414414

docs/graphs.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ A [path](#paths) that uses each [edge](#edges) once only without returning to st
110110

111111
A [path](#paths) that uses each [edge](#edges) once only and returns to starting [vertex](#nodes) is an Euler circuit.
112112

113-
If an undirected graph $G$ is connected and every vertex (not isolated) in $G$ has an even degree, then $G$ has an Euler circuit.
113+
If an undirected graph $G$ is connected and every vertex (not isolated) in $G$ has an even degree, then $G$ has an Euler circuit.
114114

115115
- Uses each **edge** once
116116
- Does return to starting vertex
@@ -989,24 +989,24 @@ function BellmanFord(list vertices, list edges, vertex source)
989989
// and fills two arrays (distance and predecessor) holding
990990
// the shortest path from the source to each vertex
991991

992-
distance := list of size n
993-
predecessor := list of size n
992+
distance := list of size n
993+
predecessor := list of size n
994994

995995
// Step 1: initialize graph_
996996
for each vertex v in vertices do
997997

998-
distance[v] := inf // Initialize the distance to all vertices to ∞
999-
predecessor[v] :=*null // And having a null predecessor
998+
distance[v] := inf // Initialize the distance to all vertices to ∞
999+
predecessor[v] :=*null // And having a null predecessor
10001000

1001-
distance[source] := 0 // The distance from the source to itself is, of course, zero
1001+
distance[source] := 0 // The distance from the source to itself is, of course, zero
10021002

10031003
// Step 2: relax edges repeatedly
10041004

10051005
repeat |V|−1 times:
10061006
for each edge (u, v) with weight w in edges do
10071007
if distance[u] + w < distance[v] then
1008-
distance[v] := distance[u] + w
1009-
predecessor[v] := u
1008+
distance[v] := distance[u] + w
1009+
predecessor[v] := u
10101010

10111011
// Step 3: check for negative-weight cycles
10121012
for each edge (u, v) with weight w in edges do

0 commit comments

Comments
 (0)