আদেশের পুনরাবৃত্তি না করে কীভাবে পুনরায় নমুনা করবেন?


12

আর এ, যদি আমি সেট.সিড () সেট করে, এবং তারপরে একটি তালিকা এলোমেলো করে নমুনা ফাংশনটি ব্যবহার করি তবে আমি কি গ্যারান্টি দিতে পারি যে আমি একই ক্রম ছাড়তে পারব না?

অর্থাত ...

set.seed(25)
limit <- 3
myindex <- seq(0,limit)
for (x in seq(1,factorial(limit))) {
    permutations <- sample(myindex)
    print(permutations)
}

এটি উত্পাদন করে

[1] 1 2 0 3
[1] 0 2 1 3
[1] 0 3 2 1
[1] 3 1 2 0
[1] 2 3 0 1
[1] 0 1 3 2

মুদ্রিত সমস্ত ক্রিয়াকলাপগুলি কি অনন্য অনুমতি হবে? বা এই বাস্তবায়নের যে পদ্ধতিতে আমি কিছু পুনরাবৃত্তি পেতে পারি তার উপর ভিত্তি করে কিছু সুযোগ আছে?

আমি গ্যারান্টিযুক্ত পুনরাবৃত্তি ছাড়াই এটি করতে সক্ষম হতে চাই। আমি যে কিভাবে করতে হবে?

(আমিও পারমন () এর মতো কোনও ফাংশন ব্যবহার করা এড়াতে চাই, যা সমস্ত ক্রিয়াকলাপ উত্পন্ন করার জন্য একটি খুব যান্ত্রিক পদ্ধতি আছে --- এটি এলোমেলো দেখাচ্ছে না))

এছাড়াও, সিডেনোট --- দেখে মনে হচ্ছে এই সমস্যাটি হ'ল ((এন!)), যদি আমি ভুল না করি।


ডিফল্টরূপে, 'নমুনা' এর আর্গুমেন্ট 'প্রতিস্থাপন' মিথ্যাতে সেট করা হয়।
অক্টোবরে

ধন্যবাদ ওকরাম, তবে এটি একটি নির্দিষ্ট নমুনার মধ্যে কাজ করছে। সুতরাং এটি নিশ্চিত করে যে 0,1,2, এবং 3 কোনও ড্রয়ের মধ্যে পুনরাবৃত্তি করবে না (সুতরাং, আমি 0,1,2,2 আঁকতে পারি না) তবে আমি জানি না যে এটি দ্বিতীয় নমুনার গ্যারান্টি দেয় কিনা, আমি আবার 0123 এর একই ক্রমটি আঁকতে পারি না। এটাই আমি প্রয়োগের ভিত্তিতে ভাবছি, বীজ নির্ধারণের সেই পুনরাবৃত্তির কোনও প্রভাব আছে কিনা।
মিটেনচপস

হ্যাঁ, শেষ পর্যন্ত আমি উত্তরগুলি পড়ে এটি বুঝতে
পেরেছিলাম

1
যদি limit12 এর বেশি হয়ে যায়, আর যখন জন্য স্থান বরাদ্দ করার চেষ্টা করে তখন আপনি সম্ভবত র‍্যামের বাইরে চলে যাবেন seq(1,factorial(limit))। (12! প্রায় 2 গিগাবাইটের প্রয়োজন, তাই 13 এর জন্য প্রায় 25 জিবি, 14 এর প্রয়োজন হবে! প্রায় 350 গিগাবাইট ইত্যাদি)
হোয়াইট

2
1: n এর সমস্ত ক্রমবিন্যাসের এলোমেলো ক্রম উত্পাদন করার জন্য একটি দ্রুত, কমপ্যাক্ট এবং মার্জিত সমাধান রয়েছে তবে শর্ত থাকে যে আপনি আরামে এন সংরক্ষণ করতে পারবেন! ব্যাপ্তি 0: (এন!) এটি সংখ্যার ফ্যাকটোরিয়াল বেস উপস্থাপনের সাথে কোনও ক্রম বিবর্তনের সারণির উপস্থাপনাকে একত্রিত করে ।
whuber

উত্তর:


9

প্রশ্নটির অনেকগুলি বৈধ ব্যাখ্যা রয়েছে। মন্তব্যগুলি - বিশেষত 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.head1 (যা উচ্চ স্তরের আকারকে 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.

এটি নিকটে, তবে আমি লক্ষ্য করেছি যে আমি 1, 2 এবং 4 এর মতো কিছু ত্রুটি পেয়েছি তবে আমি মনে করি আপনি কী বোঝাতে চেয়েছেন এবং এটি দিয়ে কাজ করতে সক্ষম হওয়া উচিত। ধন্যবাদ! > rperm(6,3) $failures [1] 9 $sample [,1] [,2] [,3] [1,] 3 1 3 [2,] 2 2 1 [3,] 1 3 2 [4,] 1 2 2 [5,] 3 3 1 [6,] 2 1 3
মিটেনচপস

4

ব্যবহার uniqueঠিক পথে কৌতুক করতে উচিত:

set.seed(2)
limit <- 3
myindex <- seq(0,limit)

endDim<-factorial(limit)
permutations<-sample(myindex)

while(is.null(dim(unique(permutations))) || dim(unique(permutations))[1]!=endDim) {
    permutations <- rbind(permutations,sample(myindex))
}
# Resulting permutations:
unique(permutations)

# Compare to
set.seed(2)
permutations<-sample(myindex)
for(i in 1:endDim)
{
permutations<-rbind(permutations,sample(myindex))
}
permutations
# which contains the same permutation twice

সঠিকভাবে কোডটি ব্যাখ্যা না করার জন্য দুঃখিত। আমি এখন খানিকটা ভিড় করছি, তবে আপনার পরে যে কোনও প্রশ্নের উত্তর দিতে পেরে আমি খুশি। এছাড়াও, উপরের
কোডটির

1
আপনি আমাকে যা দিয়েছেন তা আমি ফাংশনালাইজড করেছি: `মাইপারম <- ফাংশন (সীমা) {মাইন্ডেক্স <- সেক (0, সীমা) শেষ ডিম <-ফ্যাক্টরিয়াল (সীমা) অনুমান <স্যাম্পল (মাইন্ডেক্স) যখন (আইস.নুল (ম্লান (অনন্য) (অনুমান))) || ম্লান (অনন্য (ক্রমান্বয়ে)) [[1]! = সমাপ্তি) ut অনুমান <- আরবাইন্ড (অনুমান, নমুনা (মাইন্ডেক্স))} রিটার্ন (অনন্য (অনুমান)) It 'এটি কাজ করে, তবে আমি সীমা = 6 করতে পারে, সীমা = 7 আমার কম্পিউটারকে অতিরিক্ত উত্তপ্ত করে তোলে। = পিআই মনে করে এখনও এই সাবস্ক্রিপশন করার একটি উপায় থাকতে হবে ...
মিটেনচপস

@ মিটেনচপস, আপনি কেন বলছেন যে আমাদের অনুমতি ছাড়াই পুনরায় না বলে আর-তে পুনর্নির্মাণের জন্য অনন্য ব্যবহার প্রয়োজন? ধন্যবাদ.
ফ্রাঙ্ক

2

আমি আপনার প্রথম প্রশ্নটি কিছুটা এগিয়ে নেব এবং পরামর্শ দিচ্ছি যে যদি আপনি তুলনামূলকভাবে সংক্ষিপ্ত ভেক্টরগুলির সাথে আচরণ করে থাকেন তবে আপনি সহজেই সমস্ত অনুমতি ব্যবহার করতে পারেন permnএবং সেগুলি এলোমেলোভাবে তাদের ব্যবহার করার আদেশ দিচ্ছেন sample:

x <- combinat:::permn(1:3)
> x[sample(factorial(3),factorial(3),replace = FALSE)]
[[1]]
[1] 1 2 3

[[2]]
[1] 3 2 1

[[3]]
[1] 3 1 2

[[4]]
[1] 2 1 3

[[5]]
[1] 2 3 1

[[6]]
[1] 1 3 2

আমি এটি অনেক পছন্দ করি এবং আমি নিশ্চিত যে এটি সঠিক চিন্তাভাবনা। তবে আমার সমস্যাটি আমাকে দশে 10 পর্যন্ত চলে আসা ক্রমটি ব্যবহার করেছে, পারমন () ফ্যাক্টরিয়াল (7) এবং ফ্যাক্টরিয়াল (8) এর মধ্যে উল্লেখযোগ্যভাবে ধীর ছিল, সুতরাং আমি মনে করি 9 এবং 10 প্রতিরোধমূলকভাবে বিশাল হতে চলেছে।
মিটেনচপস

@ মিটেনচপস সত্য, তবে এটি এখনও সম্ভব আপনার সত্যিকারের কেবল একবারই এটি গণনা করা উচিত, তাই না? এগুলি একটি ফাইলে সংরক্ষণ করুন এবং তারপরে আপনার যখন প্রয়োজন হয় সেগুলি লোড করুন এবং প্রাক-সংজ্ঞায়িত তালিকা থেকে "নমুনা" দিন। সুতরাং আপনি permn(10)কেবল একবারে ধীর গণনা বা যা কিছু করতে পারেন ।
জোড়ান

ঠিক আছে, তবে আমি যদি সমস্ত অনুমতিগুলি কোথাও সঞ্চয় করে রাখি, এমনকি এটি ফ্যাকটোরিয়াল (15) এর কাছাকাছি ভেঙে যায় - কেবল সঞ্চয় করার জন্য খুব বেশি ঘর। এ কারণেই আমি ভাবছি যে বীজ নির্ধারণ করা আমাকে সম্মিলিতভাবে অনুমানের নমুনা দেওয়ার অনুমতি দেয় --- এবং যদি তা না করে তবে এটি করার জন্য যদি অ্যালগরিদম থাকে।
মিটেনচপস

@ মিটেনচপস একটি বীজ স্থাপন কার্য সম্পাদনকে প্রভাবিত করবে না, আপনি যখনই পিআরএনজি-তে কল করবেন তখনই এটি শুরু করার নিশ্চয়তা দেয়।
রোমান Luštrik

1
@ মিটেন এর জন্য সহায়তা দেখুন set.seed: এটি কীভাবে আরএনজির অবস্থা সংরক্ষণ করবে এবং পরে এটি পুনরুদ্ধার করবে তা বর্ণনা করে।
whuber
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.