আদেশের জন্য , rcppalgos দুর্দান্ত। দুর্ভাগ্যক্রমে, 12 টি ক্ষেত্রের সাথে 479 মিলিয়ন সম্ভাবনা রয়েছে যার অর্থ বেশিরভাগ লোকের জন্য অত্যধিক স্মৃতি গ্রহণ করে:
library(RcppAlgos)
elements <- 12
permuteGeneral(elements, elements)
#> Error: cannot allocate vector of size 21.4 Gb
কিছু বিকল্প আছে।
আদেশের নমুনা নিন। অর্থ, 479 মিলিয়ন এর পরিবর্তে 1 মিলিয়ন করুন। এটি করতে, আপনি ব্যবহার করতে পারেন permuteSample(12, 12, n = 1e6)
। তিনি 479 মিলিয়ন অনুমানের নমুনা ব্যতীত কিছুটা অনুরূপ পদ্ধতির জন্য @ জোসেফউডের উত্তর দেখুন;)
সৃষ্টির অনুক্রমের মূল্যায়ন করতে rcpp এ একটি লুপ তৈরি করুন। এটি স্মৃতি সংরক্ষণ করে কারণ আপনি কেবল সঠিক ফলাফলগুলি ফিরতে ফাংশনটি তৈরি করবেন।
একটি ভিন্ন অ্যালগরিদম নিয়ে সমস্যাটি দেখান। আমি এই বিকল্পটিতে ফোকাস করব।
নতুন অ্যালগরিদম ডাব্লু / সীমাবদ্ধতা
বিভাগগুলি 26 হওয়া উচিত
আমরা জানি যে উপরের নক্ষত্রের প্রতিটি লাইন বিভাগের 26 টি যোগ হওয়া দরকার perm আমরা আমাদের অনুমতিগুলি তৈরি করতে এই সীমাবদ্ধতাটি যুক্ত করতে পারি - আমাদের কেবলমাত্র সংমিশ্রণ দিন যা 26 টি পর্যন্ত যোগ করে:
# only certain combinations will add to 26
lucky_combo <- comboGeneral(12, 4, comparisonFun = '==', constraintFun = 'sum', limitConstraints = 26L)
এবিসিডি এবং ইএফজিএইচ গ্রুপগুলি
উপরের তারাটিতে , আমি তিনটি গ্রুপকে আলাদাভাবে রঙ করেছি: এবিসিডি , ইএফজিএইচ এবং আইজেএলকে । প্রথম দুটি গ্রুপেরও কোনও মিল নেই এবং এটি আগ্রহের লাইনের অংশেও রয়েছে। অতএব, আমরা আরও একটি প্রতিবন্ধকতা যুক্ত করতে পারি: 26 টির বেশি সংযোজন সংমিশ্রণের জন্য, আমাদের এবিসিডি এবং ইএফজিএইচের কোনও সংখ্যার ওভারল্যাপ না রয়েছে তা নিশ্চিত করতে হবে । আইজেএলকে বাকি 4 নম্বর বরাদ্দ দেওয়া হবে।
library(RcppAlgos)
lucky_combo <- comboGeneral(12, 4, comparisonFun = '==', constraintFun = 'sum', limitConstraints = 26L)
two_combo <- comboGeneral(nrow(lucky_combo), 2)
unique_combos <- !apply(cbind(lucky_combo[two_combo[, 1], ], lucky_combo[two_combo[, 2], ]), 1, anyDuplicated)
grp1 <- lucky_combo[two_combo[unique_combos, 1],]
grp2 <- lucky_combo[two_combo[unique_combos, 2],]
grp3 <- t(apply(cbind(grp1, grp2), 1, function(x) setdiff(1:12, x)))
গোষ্ঠীগুলির মাধ্যমে পারম्यूट করুন
আমাদের প্রতিটি গ্রুপের সমস্ত অনুমতি খুঁজে পাওয়া দরকার। এটি হ'ল, আমাদের কেবল সংমিশ্রণগুলি রয়েছে যা 26 টি পর্যন্ত যুক্ত হয় For উদাহরণস্বরূপ, আমাদের নেওয়া 1, 2, 11, 12
এবং তৈরি করা দরকার 1, 2, 12, 11; 1, 12, 2, 11; ...
।
#create group perms (i.e., we need all permutations of grp1, grp2, and grp3)
n <- 4
grp_perms <- permuteGeneral(n, n)
n_perm <- nrow(grp_perms)
# We create all of the permutations of grp1. Then we have to repeat grp1 permutations
# for all grp2 permutations and then we need to repeat one more time for grp3 permutations.
stars <- cbind(do.call(rbind, lapply(asplit(grp1, 1), function(x) matrix(x[grp_perms], ncol = n)))[rep(seq_len(sum(unique_combos) * n_perm), each = n_perm^2), ],
do.call(rbind, lapply(asplit(grp2, 1), function(x) matrix(x[grp_perms], ncol = n)[rep(1:n_perm, n_perm), ]))[rep(seq_len(sum(unique_combos) * n_perm^2), each = n_perm), ],
do.call(rbind, lapply(asplit(grp3, 1), function(x) matrix(x[grp_perms], ncol = n)[rep(1:n_perm, n_perm^2), ])))
colnames(stars) <- LETTERS[1:12]
চূড়ান্ত গণনা
শেষ পদক্ষেপটি গণিত করা। আমি আরও কার্যকরী প্রোগ্রামিং করতে এখানে lapply()
এবং ব্যবহার করি Reduce()
- অন্যথায়, প্রচুর কোড ছয়বার টাইপ করা হবে। গণিতের কোডটির আরও বিশদ ব্যাখ্যার জন্য আসল সমাধানটি দেখুন।
# creating a list will simplify our math as we can use Reduce()
col_ind <- list(c('A', 'B', 'C', 'D'), #these two will always be 26
c('E', 'F', 'G', 'H'), #these two will always be 26
c('I', 'C', 'J', 'H'),
c('D', 'J', 'G', 'K'),
c('K', 'F', 'L', 'A'),
c('E', 'L', 'B', 'I'))
# Determine which permutations result in a lucky star
L <- lapply(col_ind, function(cols) rowSums(stars[, cols]) == 26)
soln <- Reduce(`&`, L)
# A couple of ways to analyze the result
rbind(stars[which(soln),], stars[which(soln), c(1,8, 9, 10, 11, 6, 7, 2, 3, 4, 5, 12)])
table(Reduce('+', L)) * 2
2 3 4 6
2090304 493824 69120 960
সোয়াপিং ABCD এবং EFGH
উপরের কোড শেষে, আমি সুবিধা গ্রহণ যে আমরা অদলবদল করতে পারেন ABCD
এবং EFGH
অবশিষ্ট একাধিক বিন্যাসন জন্য। হ্যাঁ, আমরা দুটি গ্রুপকে অদলবদল করতে এবং সঠিক হতে পারি তা নিশ্চিত করার জন্য এখানে কোডটি রয়েছে:
# swap grp1 and grp2
stars2 <- stars[, c('E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'I', 'J', 'K', 'L')]
# do the calculations again
L2 <- lapply(col_ind, function(cols) rowSums(stars2[, cols]) == 26)
soln2 <- Reduce(`&`, L2)
identical(soln, soln2)
#[1] TRUE
#show that col_ind[1:2] always equal 26:
sapply(L, all)
[1] TRUE TRUE FALSE FALSE FALSE FALSE
কর্মক্ষমতা
শেষ পর্যন্ত, আমরা 479 অনুক্রমের মধ্যে কেবলমাত্র 1.3 মিলিয়ন মূল্যায়ন করেছি এবং কেবল 550 এমবি র্যামের মাধ্যমেই এলোমেলো হয়েছি। এটি চালাতে প্রায় 0.7s লাগে
# A tibble: 1 x 13
expression min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc
<bch:expr> <bch> <bch:> <dbl> <bch:byt> <dbl> <int> <dbl>
1 new_algo 688ms 688ms 1.45 550MB 7.27 1 5
x<- 1:elements
এবং আরও গুরুত্বপূর্ণভাবেL1 <- y[,1] + y[,3] + y[,6] + y[,8]
। এটি আপনার মেমরির সমস্যাটিতে আসলেই সহায়তা করবে না যাতে আপনি সর্বদা আরসিপিপি