Ad esempio, si consideri il numero 96. Esso può essere scritto in modi seguenti:R algoritmo per generare tutti i possibili fattorizzazione di un numero
1. 96
2. 48 * 2
3. 24 * 2 * 2
4. 12 * 2 * 2 * 2
5. 6 * 2 * 2 * 2 * 2
6. 3 * 2 * 2 * 2 * 2 * 2
7. 4 * 3 * 2 * 2 * 2
8. 8 * 3 * 2 * 2
9. 6 * 4 * 2 * 2
10. 16 * 3 * 2
11. 4 * 4 * 3 * 2
12. 12 * 4 * 2
13. 8 * 6 * 2
14. 32 * 3
15. 8 * 4 * 3
16. 24 * 4
17. 6 * 4 * 4
18. 16 * 6
19. 12 * 8
So che questo è legato alle partizioni qualsiasi numero scritto come il potere , n., di un singolo primo, p, è semplicemente il numero di modi in cui è possibile scrivere n. Ad esempio, per trovare tutte le fattorizzazioni di 2^5, dobbiamo trovare tutti i modi per scrivere 5. Essi sono:
- 1 + 1 + 1 + 1 + 1 == >> 2^1 * 2^1 * 2^1 * 2^1 * 2^1
- 1 + 1 + 1 + 2 == >> 2^1 * 2^1 * 2^1 * 2^2
- 1 + 1 + 3 == >> 2^1 * 2^1 * 2^3
- 1 + 2 + 2 == >> 2^1 * 2^2 * 2^2
- 1 + 4 == >> 2^1 * 2^4
- 2 + 3 == >> 2^2 * 2^3
- 5 == >> 2^5
Ho trovato un articolo meraviglioso di Jerome Kelleher sugli algoritmi di generazione delle partizioni here. Ho adattato uno dei suoi algoritmi di Python per R. Il codice è qui sotto:
library(partitions) ## using P(n) to determine number of partitions of an integer
IntegerPartitions <- function(n) {
a <- 0L:n
k <- 2L
a[2L] <- n
MyParts <- vector("list", length=P(n))
count <- 0L
while (!(k==1L)) {
x <- a[k-1L]+1L
y <- a[k]-1L
k <- k-1L
while (x<=y) {a[k] <- x; y <- y-x; k <- k+1L}
a[k] <- x+y
count <- count+1L
MyParts[[count]] <- a[1L:k]
}
MyParts
}
ho tentato di estendere questo metodo per i numeri con più uno che un fattore primario, ma il mio codice ottenuto molto goffo. Dopo aver lottato con questa idea per un po ', ho deciso di provare una strada diversa. Il mio nuovo algoritmo non fa uso di generare partizioni di sorta. È più un algoritmo di "lookback" che sfrutta le fatture che sono già state generate. Il codice è qui sotto:
FactorRepresentations <- function(n) {
MyFacts <- EfficientFactorList(n)
MyReps <- lapply(1:n, function(x) x)
for (k in 4:n) {
if (isprime(k)) {next}
myset <- MyFacts[[k]]
mylist <- vector("list")
mylist[[1]] <- k
count <- 1L
for (j in 2:ceiling(length(myset)/2)) {
count <- count+1L
temp <- as.integer(k/myset[j])
myvec <- sort(c(myset[j], temp), decreasing=TRUE)
mylist[[count]] <- myvec
MyTempRep <- MyReps[[temp]]
if (isprime(temp) || temp==k) {next}
if (length(MyTempRep)>1) {
for (i in 1:length(MyTempRep)) {
count <- count+1L
myvec <- sort(c(myset[j], MyTempRep[[i]]), decreasing=TRUE)
mylist[[count]] <- myvec
}
}
}
MyReps[[k]] <- unique(mylist)
}
MyReps
}
La prima funzione nel codice sopra è semplicemente una funzione che genera tutti i fattori. Ecco il codice se siete curiosi:
EfficientFactorList <- function(n) {
MyFactsList <- lapply(1:n, function(x) 1)
for (j in 2:n) {
for (r in seq.int(j, n, j)) {MyFactsList[[r]] <- c(MyFactsList[[r]], j)}
}
MyFactsList
}
mio algoritmo è solo bene se siete interessati solo con i numeri di meno di 10.000 (che genera tutte le fattorizzazioni per ogni numero < = 10.000 in circa 17 secondi), ma sicuramente non scala bene. Mi piacerebbe trovare un algoritmo che abbia la stessa premessa di generare un elenco di fatture per ogni numero minore o uguale a n poiché alcune delle applicazioni che ho in mente faranno riferimento a una data fattorizzazione più volte, avendo così in una lista dovrebbe essere più veloce di generarlo al volo ogni volta (so che qui c'è un costo di memoria).
Questo non è un problema semplice (ovviamente) ma nel caso in cui non lo aveste ancora trovato, ecco la voce pertinente dall'Enciclopedia on-line delle sequenze intere: https://oeis.org/A001055 –
Questo è molto utile, anche se questo fornisce solo il numero totale di fatture e non le fatture stesse. Ad esempio, per n = 96 come sopra, dà 19. –