POP77001 Computer Programming for Social Scientists
Linear search using exhaustive enumeration.
Anything that can go wrong will go wrong.
Edward Murphy
linear_search <- function(v, x) {
n <- length(v) # 2 steps (call to length() function and assignment `<-`)
# n steps + 1 step (for seq_len(n) call)
for (i in seq_len(n)) {
# 3n steps (n steps for `[`(v, i), another n steps for `==` and n calls to `if`)
if (v[i] == x) {
return(TRUE) # 1 step
}
}
return(FALSE) # 1 step
}binary_search <- function(v, x) {
low <- 1
high <- length(v)
iters <- 1
while (low <= high) {
m <- (low + high) %/% 2
if (v[m] < x) {
low <- m + 1
} else if (v[m] > x) {
high <- m - 1
} else {
print(paste0("Number of iterations: ", as.character(iters)))
return(iters) # return(TRUE)
}
iters <- iters + 1
}
return(iters) # return(FALSE)
}[1] "Number of iterations: 1000"
[1] "Number of iterations: 1000000"
| Big-O notation | Running time |
|---|---|
| \(O(1)\) | constant |
| \(O(\log n)\) | logarithmic |
| \(O(n)\) | linear |
| \(O(n \log n)\) | log-linear |
| \(O(n^c)\) | polynomial |
| \(O(c^n)\) | exponential |
| \(O(n!)\) | factorial |
[1] "Number of iterations: 4"
[1] "Number of iterations: 5"
[1] "Number of iterations: 7"
[1] "Number of iterations: 8"
[1] "Number of iterations: 10"
[1] "Number of iterations: 10"
[1] "Number of iterations: 20"
[1] "Number of iterations: 100"
[1] "Number of iterations: 200"
[1] "Number of iterations: 1000"
x <- c(10, 20, 100, 200, 1000)
constant_complexity <- rep(10, length(x))
log_complexity <- c(bs_10, bs_20, bs_100, bs_200, bs_1000)
linear_complexity <- c(ls_10, ls_20, ls_100, ls_200, ls_1000)
plot(x, linear_complexity, type = "n", main = "O(1) vs O(log(n)) vs O(n)", xlab = "Input size", ylab = "Time")
lines(x, constant_complexity, type = "l", col = "black", lty = 1, lwd = 3)
lines(x, log_complexity, type = "l", col = "red", lty = 2, lwd = 3)
lines(x, linear_complexity, type = "l", col = "blue", lty = 3, lwd = 3)
legend("topleft", legend = c("Constant(10)", "Logarithmic", "Linear"),
col = c("black", "red", "blue"), lty = 1:3, cex = 1.5)sorted() in Python).# Check whether one vector is contained within another vector
is_subset <- function(v1, v2) {
n <- length(v1)
m <- length(v2)
iters <- 1
for (i in seq_len(n)) {
matched <- FALSE
for (j in seq_len(m)) {
iters <- iters + 1
if (v1[i] == v2[j]) {
matched <- TRUE
break
}
}
if (isTRUE(matched)) {
print(paste0("Number of iterations: ", as.character(iters)))
return(iters) # return(TRUE)
}
}
print(paste0("Number of iterations: ", as.character(iters)))
return(iters) # return(FALSE)
}[1] "Number of iterations: 111"
[1] "Number of iterations: 421"
[1] "Number of iterations: 10101"
[1] "Number of iterations: 40201"
[1] "Number of iterations: 1001001"
log_linear_complexity <- x * log(x)
quadratic_complexity <- c(is_10, is_20, is_100, is_200, is_1000)
plot(x, quadratic_complexity, type = "n", main = "O(n) vs O(nlog(n)) vs O(n^2)", xlab = "Input size", ylab = "Time")
lines(x, linear_complexity, type = "l", col = "black", lty = 1, lwd = 3)
lines(x, log_linear_complexity, type = "l", col = "red", lty = 2, lwd = 3)
lines(x, quadratic_complexity, type = "l", col = "blue", lty = 3, lwd = 3)
legend("topleft", legend = c("Linear", "Log-Linear", "Quadratic"),
col = c("black", "red", "blue"), lty = 1:3, cex = 1.5)x <- 1:25
quadratic_complexity <- x ^ 2
exponential_complexity <- 10 ^ x
factorial_complexity <- factorial(x)
plot(x, factorial_complexity, type = "n", main = "O(n^2) vs O(10^n) vs O(n!)", xlab = "Input size", ylab = "Time")
lines(x, quadratic_complexity, type = "l", col = "black", lty = 1, lwd = 3)
lines(x, exponential_complexity, type = "l", col = "red", lty = 2, lwd = 3)
lines(x, factorial_complexity, type = "l", col = "blue", lty = 3, lwd = 3)
legend("topleft", legend = c("Quadratic", "Exponential", "Factorial"),
col = c("black", "red", "blue"), lty = 1:3, cex = 1.5)sort() methods in R is \(O(n^{4/3})\)).is_subset() function above).(xkcd)