প্রশ্নটির অনেকগুলি বৈধ ব্যাখ্যা রয়েছে। মন্তব্যগুলি - বিশেষত 15 বা ততোধিক উপাদানগুলির একটি নির্দেশকারী ক্রমগুলির প্রয়োজন (15! = 1307674368000 বড় হচ্ছে) - প্রস্তাবিত যা চান তা হ'ল প্রতিস্থাপন ছাড়াই অপেক্ষাকৃত ছোট এলোমেলো নমুনা! = এন * (এন -১) (এন -২) ... * 2 * 1 এর 1: এন এর ক্রিয়াকলাপ। যদি এটি সত্য হয় তবে কার্যকর সমাধান রয়েছে somewhat
নিম্নলিখিত ফাংশন, rperm
দুটি আর্গুমেন্ট গ্রহণ করে n
(নমুনা অনুসারে অনুমানের আকার) এবং m
(আকার আঁকার জন্য ক্রমের সংখ্যা)। যদি মি এর নিকটবর্তী হয় বা এন ছাড়িয়ে যায়, তবে ফাংশনটি দীর্ঘ সময় নিতে পারে এবং অনেক এনএ মান দেয়: এটি যখন এন তুলনামূলকভাবে বড় হয় (তখন বলুন, 8 বা তার বেশি) এবং এম এন এর চেয়ে অনেক ছোট হয় তখন এটি ব্যবহারের উদ্দেশ্যে! এটি এখনও পর্যন্ত পাওয়া ক্রমগুলির একটি স্ট্রিং প্রতিনিধিত্বকে ক্যাশে করে এবং তারপরে একটি নতুন সন্ধান না পাওয়া পর্যন্ত নতুন ক্রমবিন্যাস (এলোমেলোভাবে) তৈরি করে কাজ করে। এটি আর-এর সহযোগী তালিকা-ইন্ডেক্সিং ক্ষমতাটি পূর্বে সন্ধান করা ক্রমগুলির তালিকা দ্রুত অনুসন্ধান করার ক্ষমতা ব্যবহার করে।
rperm <- function(m, size=2) { # Obtain m unique permutations of 1:size
# Function to obtain a new permutation.
newperm <- function() {
count <- 0 # Protects against infinite loops
repeat {
# Generate a permutation and check against previous ones.
p <- sample(1:size)
hash.p <- paste(p, collapse="")
if (is.null(cache[[hash.p]])) break
# Prepare to try again.
count <- count+1
if (count > 1000) { # 1000 is arbitrary; adjust to taste
p <- NA # NA indicates a new permutation wasn't found
hash.p <- ""
break
}
}
cache[[hash.p]] <<- TRUE # Update the list of permutations found
p # Return this (new) permutation
}
# Obtain m unique permutations.
cache <- list()
replicate(m, newperm())
} # Returns a `size` by `m` matrix; each column is a permutation of 1:size.
প্রকৃতি replicate
হ'ল কলাম ভেক্টর হিসাবে অনুমতিগুলি ফেরত দেওয়া ; উদাহরণস্বরূপ , নিম্নলিখিত স্থানান্তরিত মূল প্রশ্নে একটি উদাহরণ পুনরুত্পাদন করে :
> set.seed(17)
> rperm(6, size=4)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 2 4 4 3 4
[2,] 3 4 1 3 1 2
[3,] 4 1 3 2 2 3
[4,] 2 3 2 1 4 1
সময়কালগুলি ছোট থেকে মাঝারি মানের প্রায় 10,000 অবধি মানের জন্য দুর্দান্ত তবে বড় সমস্যার জন্য অবনমিত হয়। উদাহরণস্বরূপ, এন = 1000 উপাদানগুলির এম = 10,000 ক্রিয়াকলাপের একটি নমুনা (10 মিলিয়ন মানের একটি ম্যাট্রিক্স) 10 সেকেন্ডে প্রাপ্ত হয়েছিল; আউটপুট (৪০০,০০০ এন্ট্রির একটি ম্যাট্রিক্স) অনেক ছোট হলেও, এন = ২০ উপাদানগুলির এম = ২০,০০০ ক্রমের অনুকরণের জন্য 11 সেকেন্ডের প্রয়োজন; এবং এন = 20 উপাদানগুলির মি = 100,000 ক্রিয়াকলাপের কম্পিউটিং নমুনাগুলি 260 সেকেন্ড পরে বাতিল করা হয়েছে (সমাপ্তির জন্য অপেক্ষা করার ধৈর্য আমার নেই)। এই স্কেলিং সমস্যাটি আর এর সহযোগী সম্বোধনে স্কেলিং অদক্ষতার সাথে সম্পর্কিত বলে মনে হয়। 1000 বা এর বেশি গ্রুপে নমুনা তৈরি করে কেউ এর চারপাশে কাজ করতে পারে, তারপরে সেই নমুনাগুলিকে একটি বড় নমুনায় একত্রিত করে এবং নকলগুলি সরিয়ে ফেলতে পারে।
সম্পাদন করা
দুটি ক্যাশের একটি শ্রেণিবিন্যাসে ক্যাশে ভেঙে আমরা লিনিয়ার অ্যাসেম্পোটিক পারফরম্যান্সের কাছাকাছি পৌঁছে যেতে পারি, যাতে আর কখনও কোনও বৃহত তালিকার মধ্যে অনুসন্ধান করতে না হয়। ধারণাগতভাবে (যদিও এটি প্রয়োগ করা হয়নি), একটি ক্রমের প্রথম উপাদানগুলির দ্বারা সূচিযুক্ত একটি অ্যারে তৈরি করুন । এই অ্যারেতে প্রবেশকারীরা হ'ল প্রথম উপাদানগুলি ভাগ করে নেওয়ার সমস্ত ক্রয়ের তালিকা । কোনও ক্রিয়াকলাপ দেখা গেছে কিনা তা পরীক্ষা করতে, ক্যাশে এটির প্রবেশদ্বার খুঁজতে তার প্রথম উপাদানগুলি ব্যবহার করুন এবং তারপরে সেই প্রবেশের মধ্যে সেই ক্রমানুসন্ধানটি অনুসন্ধান করুন। সমস্ত তালিকার প্রত্যাশিত মাপের ভারসাম্য বজায় রাখতে আমরা বেছে নিতে পারি । প্রকৃত বাস্তবায়ন একটি ব্যবহার করে নাkkkkk-ফোল্ড অ্যারে, যা পর্যাপ্ত সাধারণতায় প্রোগ্রাম করা কঠিন, তবে পরিবর্তে অন্য তালিকা ব্যবহার করে।
অনুরোধ অনুসারে বিভিন্ন আকারের ক্রম ছাড়ার জন্য অনুরোধ করা হয়েছে:
Number Size=10 Size=15 Size=1000 size=10000 size=100000
10 0.00 0.00 0.02 0.08 1.03
100 0.01 0.01 0.07 0.64 8.36
1000 0.08 0.09 0.68 6.38
10000 0.83 0.87 7.04 65.74
100000 11.77 10.51 69.33
1000000 195.5 125.5
(আকার = 10 থেকে আকার = 15 পর্যন্ত আপাতদৃষ্টিতে অসাধারণ গতিবেগ হ'ল কারণ ক্যাশের প্রথম স্তরটি আকারের 15 এর চেয়ে বড় হয়, দ্বিতীয় স্তরের তালিকাগুলিতে গড় প্রবেশের সংখ্যা কমিয়ে দেয়, যার ফলে আর এর সহযোগী অনুসন্ধানকে ত্বরান্বিত করা হয় some র্যামে ব্যয়, উপরের স্তরের ক্যাশের আকার বাড়িয়ে দ্রুত কার্যকর করা যায় Just মাত্র k.head
1 (যা উচ্চ স্তরের আকারকে 10 দ্বারা বাড়ায় ) rperm(100000, size=10)
উদাহরণস্বরূপ ১১.7777 সেকেন্ড থেকে ৮.72২ সেকেন্ডে বৃদ্ধি পেয়েছে .র্ধ্ব-স্তর তৈরি করা 10 গুণ বড় ক্যাশে এখনও 8.51 সেকেন্ডে ক্লকিং করে কোনও প্রশংসনীয় লাভ হয়নি)
১০০ টি উপাদানের এক হাজার 10,000 অনন্য ক্রিয়াকলাপ (সমস্ত 10 এর একটি যথেষ্ট অংশ! = প্রায় 3.63 মিলিয়ন এইরকম অনুমানের) ব্যতীত, কার্যত কোনও সংঘর্ষ সনাক্ত করা যায় নি। এই ব্যতিক্রমী ক্ষেত্রে, 169,301 সংঘর্ষ ছিল, তবে কোনও সম্পূর্ণ ব্যর্থতা হয়নি (বাস্তবে এক মিলিয়ন অনন্য অনুভূতি প্রাপ্ত হয়েছিল)।
নোট করুন যে বড় ক্রম ছাড়নের আকার (20 বা ততোধিকের বেশি) এর সাথে, এমনকি 10,000,000,000 এর আকারের আকারে এমনকি দুটি নমুনা পাওয়ার সম্ভাবনা অদৃশ্য। সুতরাং, এই সমাধানটি প্রাথমিকভাবে সেই পরিস্থিতিতে কার্যকর হয় যেখানে (ক) এবং মধ্যে (খ) এর অনন্য অনুমানের বৃহত সংখ্যক বা ততক্ষণে উপাদান তৈরি করা যায়, তবুও (গ) সমস্ত চেয়ে যথেষ্ট কমক্রমবিকাশ প্রয়োজন।n=5n=15n!
ওয়ার্কিং কোড অনুসরণ।
rperm <- function(m, size=2) { # Obtain m unique permutations of 1:size
max.failures <- 10
# Function to index into the upper-level cache.
prefix <- function(p, k) { # p is a permutation, k is the prefix size
sum((p[1:k] - 1) * (size ^ ((1:k)-1))) + 1
} # Returns a value from 1 through size^k
# Function to obtain a new permutation.
newperm <- function() {
# References cache, k.head, and failures in parent context.
# Modifies cache and failures.
count <- 0 # Protects against infinite loops
repeat {
# Generate a permutation and check against previous ones.
p <- sample(1:size)
k <- prefix(p, k.head)
ip <- cache[[k]]
hash.p <- paste(tail(p,-k.head), collapse="")
if (is.null(ip[[hash.p]])) break
# Prepare to try again.
n.failures <<- n.failures + 1
count <- count+1
if (count > max.failures) {
p <- NA # NA indicates a new permutation wasn't found
hash.p <- ""
break
}
}
if (count <= max.failures) {
ip[[hash.p]] <- TRUE # Update the list of permutations found
cache[[k]] <<- ip
}
p # Return this (new) permutation
}
# Initialize the cache.
k.head <- min(size-1, max(1, floor(log(m / log(m)) / log(size))))
cache <- as.list(1:(size^k.head))
for (i in 1:(size^k.head)) cache[[i]] <- list()
# Count failures (for benchmarking and error checking).
n.failures <- 0
# Obtain (up to) m unique permutations.
s <- replicate(m, newperm())
s[is.na(s)] <- NULL
list(failures=n.failures, sample=matrix(unlist(s), ncol=size))
} # Returns an m by size matrix; each row is a permutation of 1:size.