লাকি 26 গেমটি সমাধান করতে আর ব্যবহার করে


15

আমি আমার পুত্রকে দেখানোর চেষ্টা করছি যে কোনও কোড দ্বারা উত্থাপিত কোনও সমস্যা সমাধানের জন্য কীভাবে কোডিং ব্যবহার করা যেতে পারে পাশাপাশি এটি কীভাবে বড় ডেটা পরিচালনা করে seeing প্রশ্নে থাকা খেলাকে "লাকি 26" বলা হয়। এই গেমের সংখ্যাগুলিতে (কোনও ডুপ্লিকেট ছাড়াই 1-12) 12 টি পয়েন্টে ডেভিডের একটি তারাতে অবস্থিত (6 ভার্টেক্স, 6 ছেদটি) এবং 4 সংখ্যার 6 টি লাইন অবশ্যই 26 টিতে যোগ করতে হবে 47 প্রায় 479 মিলিয়ন সম্ভাবনার (12P12) ) আপাতদৃষ্টিতে 144 টি সমাধান রয়েছে। আমি নিম্নলিখিত হিসাবে আর এ কোড করার চেষ্টা করেছি কিন্তু মেমরিটি মনে হচ্ছে এটি একটি সমস্যা। সদস্যদের সময় থাকলে উত্তরটি অগ্রসর করার জন্য আমি যে কোনও পরামর্শের ব্যাপক প্রশংসা করব। অগ্রিম সদস্যদের ধন্যবাদ।

library(gtools)

x=c()
elements <- 12
for (i in 1:elements)
{ 
    x[i]<-i
}

soln=c()            

y<-permutations(n=elements,r=elements,v=x)  
j<-nrow(y)
for (i in 1:j) 
{
L1 <- y[i,1] + y[i,3] + y[i,6] + y[i,8]
L2 <- y[i,1] + y[i,4] + y[i,7] + y[i,11]
L3 <- y[i,8] + y[i,9] + y[i,10] + y[i,11]
L4 <- y[i,2] + y[i,3] + y[i,4] + y[i,5]
L5 <- y[i,2] + y[i,6] + y[i,9] + y[i,12]
L6 <- y[i,5] + y[i,7] + y[i,10] + y[i,12]
soln[i] <- (L1 == 26)&(L2 == 26)&(L3 == 26)&(L4 == 26)&(L5 == 26)&(L6 == 26) 
}

z<-which(soln)
z

3
আমি যুক্তি বুঝতে পারি না তবে আপনার নিজের পদ্ধতির ভেক্টরাইজ করা উচিত। x<- 1:elementsএবং আরও গুরুত্বপূর্ণভাবে L1 <- y[,1] + y[,3] + y[,6] + y[,8]। এটি আপনার মেমরির সমস্যাটিতে আসলেই সহায়তা করবে না যাতে আপনি সর্বদা আরসিপিপি
কোলে

4
দয়া করে rm(list=ls())আপনার এমআরই রাখবেন না । যদি কেউ সক্রিয় অধিবেশনে কপি-পেস্ট করে তবে তারা নিজের ডেটা হারাতে পারে।
dww

আরএম (তালিকা = ls ()) এর জন্য
ক্ষমা প্রার্থনা

আপনি কি নিশ্চিত যে কেবল ১৪৪ জন আছে? আমি এখনও এটিতে কাজ করছি এবং আমি 480 পেয়েছি তবে আমার বর্তমান পদ্ধতির বিষয়ে আমি কিছুটা অনিশ্চিত।
কোল

1
@ কোল, আমি 960 টি সমাধান পাচ্ছি।
জোসেফ উড

উত্তর:


3

এখানে অন্য পদ্ধতির। এটা একটা উপর ভিত্তি করে এর MathWorks ব্লগ পোস্ট দ্বারা Cleve Moler , প্রথম ম্যাটল্যাব লেখক।

স্মৃতি বাঁচাতে লেখক প্রথম উপাদানটিকে শীর্ষস্থানীয় উপাদান হিসাবে এবং 7 তমটিকে বেস উপাদান হিসাবে রেখে কেবলমাত্র 10 টি উপাদানকে অনুমতি দেয়। অতএব, শুধুমাত্র 10! == 3628800আদেশের পরীক্ষা করা দরকার।
নীচের কোডে,

  1. উপাদানের একাধিক বিন্যাসন জেনারেট করুন 1থেকে 1010! == 3628800তাদের মোট আছে ।
  2. 11শীর্ষস্থানীয় উপাদান হিসাবে চয়ন করুন এবং এটি স্থির রাখুন। অ্যাসাইনমেন্টগুলি যেখানে শুরু হয় তা সত্যিই গুরুত্বপূর্ণ নয়, অন্যান্য উপাদানগুলি সঠিক আপেক্ষিক অবস্থানে থাকবে।
  3. তারপরে একটি forলুপে 12 তম উপাদানটিকে 2 য় অবস্থান, তৃতীয় অবস্থান, ইত্যাদিতে নির্ধারণ করুন ।

এর বেশিরভাগ সমাধান উত্পাদন করা উচিত, আবর্তন এবং প্রতিবিম্ব দেওয়া বা নেওয়া। তবে এটি গ্যারান্টি দেয় না যে সমাধানগুলি অনন্য। এটি যুক্তিসঙ্গত দ্রুত।

elements <- 12
x <- seq_len(elements)
p <- gtools::permutations(n = elements - 2, r = elements - 2, v = x[1:10])  

i1 <- c(1, 3, 6, 8)
i2 <- c(1, 4, 7, 11)
i3 <- c(8, 9, 10, 11)
i4 <- c(2, 3, 4, 5)
i5 <- c(2, 6, 9, 12)
i6 <- c(5, 7, 10, 12)

result <- vector("list", elements - 1)
for(i in 0:10){
  if(i < 1){
    p2 <- cbind(11, 12, p)
  }else if(i == 10){
    p2 <- cbind(11, p, 12)
  }else{
    p2 <- cbind(11, p[, 1:i], 12, p[, (i + 1):10])
  }
  L1 <- rowSums(p2[, i1]) == 26
  L2 <- rowSums(p2[, i2]) == 26
  L3 <- rowSums(p2[, i3]) == 26
  L4 <- rowSums(p2[, i4]) == 26
  L5 <- rowSums(p2[, i5]) == 26
  L6 <- rowSums(p2[, i6]) == 26

  i_sol <- which(L1 & L2 & L3 & L4 & L5 & L6)
  result[[i + 1]] <- if(length(i_sol) > 0) p2[i_sol, ] else NA
}
result <- do.call(rbind, result)
dim(result)
#[1] 82 12

head(result)
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
#[1,]   11   12    1    3   10    5    8    9    7     6     4     2
#[2,]   11   12    1    3   10    8    5    6    4     9     7     2
#[3,]   11   12    1    7    6    4    3   10    2     9     5     8
#[4,]   11   12    3    2    9    8    6    4    5    10     7     1
#[5,]   11   12    3    5    6    2    9   10    8     7     1     4
#[6,]   11   12    3    6    5    4    2    8    1    10     7     9

6

আসলে 960 টি সমাধান রয়েছে। নীচে আমরা 4 টি কোর ব্যবহার করে সমাধান পেতে Rcpp, RcppAlgos* , এবং parallelপ্যাকেজটি 6 secondsব্যবহার করি। এমনকি যদি আপনি বেস আর এর সাথে একটি একক থ্রেডযুক্ত পদ্ধতির ব্যবহার করতে চান lapply, সমাধানটি প্রায় 25 সেকেন্ডের মধ্যে ফিরে আসে।

প্রথমত, আমরা একটি সাধারণ অ্যালগরিদম লিখি C++যা একটি নির্দিষ্ট ক্রমান্বন পরীক্ষা করে। আপনি লক্ষ করবেন যে আমরা সমস্ত ছয়টি লাইন সঞ্চয় করতে একটি অ্যারে ব্যবহার করি। এটি কার্য সম্পাদনের জন্য কারণ আমরা 6 স্বতন্ত্র অ্যারে ব্যবহারের চেয়ে ক্যাশে মেমরিটিকে আরও কার্যকরভাবে ব্যবহার করি। আপনার মনে রাখতে হবে যে C++শূন্য ভিত্তিক সূচক ব্যবহার করে।

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::plugins(cpp11)]]

constexpr int index26[24] = {0, 2, 5, 7,
                             0, 3, 6, 10,
                             7, 8, 9, 10,
                             1, 2, 3, 4,
                             1, 5, 8, 11,
                             4, 6, 9, 11};

// [[Rcpp::export]]
IntegerVector DavidIndex(IntegerMatrix mat) {
    const int nRows = mat.nrow();
    std::vector<int> res;

    for (int i = 0; i < nRows; ++i) {
        int lucky = 0;

        for (int j = 0, s = 0, e = 4;
             j < 6 && j == lucky; ++j, s += 4, e += 4) {

            int sum = 0;

            for (int k = s; k < e; ++k)
                sum += mat(i, index26[k]);

            lucky += (sum == 26);
        }

        if (lucky == 6) res.push_back(i);
    }

    return wrap(res);
}

এখন, যুক্তিগুলি lowerএবং upperযুক্তিগুলি ব্যবহার করে permuteGeneral, আমরা ক্রমান্বয়ে কিছু জেনারেট তৈরি করতে পারি এবং স্মৃতি স্মরণে রাখতে পৃথকভাবে এটি পরীক্ষা করতে পারি। নীচে, আমি একবারে প্রায় ৪. million মিলিয়ন ক্রিয়াকলাপ পরীক্ষা করতে বেছে নিয়েছি। আউটপুটটি 12 এর ক্রমবিন্যাসের অভিধানিক সূচকগুলি দেয়! যেমন ভাগ্যবান 26 শর্তটি সন্তুষ্ট।

library(RcppAlgos)
## N.B. 4790016L evenly divides 12!, so there is no need to check
## the upper bound on the last iteration below

system.time(solution <- do.call(c, parallel::mclapply(seq(1L, factorial(12), 4790016L), function(x) {
    perms <- permuteGeneral(12, 12, lower = x, upper = x + 4790015)
    ind <- DavidIndex(perms)
    ind + x
}, mc.cores = 4)))

  user  system elapsed 
13.005   6.258   6.644

## Foregoing the parallel package and simply using lapply,
## we obtain the solution in about 25 seconds:
##   user  system elapsed 
## 18.495   6.221  24.729

এখন, আমরা ব্যবহারটি যাচাই করি permuteSampleএবং সেই যুক্তি sampleVecযা আপনাকে নির্দিষ্ট অনুমতি প্রদান করতে দেয় (উদাহরণস্বরূপ আপনি যদি 1 পাস করেন তবে এটি আপনাকে প্রথম অনুমানের (অর্থাত্ 1:12)) দেবে।

system.time(Lucky26 <- permuteSample(12, 12, sampleVec=solution))
 user  system elapsed 
0.001   0.000   0.001

head(Lucky26)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    2    4   12    8   10    6   11    5     3     7     9
[2,]    1    2    6   10    8   12    4    7    3     5    11     9
[3,]    1    2    7   11    6    8    5   10    4     3     9    12
[4,]    1    2    7   12    5   10    4    8    3     6     9    11
[5,]    1    2    8    9    7   11    4    6    3     5    12    10
[6,]    1    2    8   10    6   12    4    5    3     7    11     9

tail(Lucky26)
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[955,]   12   11    5    3    7    1    9    8   10     6     2     4
[956,]   12   11    5    4    6    2    9    7   10     8     1     3
[957,]   12   11    6    1    8    3    9    5   10     7     4     2
[958,]   12   11    6    2    7    5    8    3    9    10     4     1
[959,]   12   11    7    3    5    1    9    6   10     8     2     4
[960,]   12   11    9    1    5    3    7    2    8    10     6     4

অবশেষে, আমরা আমাদের সমাধানটি বেস আর দিয়ে যাচাই করি rowSums:

all(rowSums(Lucky26[, c(1, 3, 6, 8]) == 26)
[1] TRUE

all(rowSums(Lucky26[, c(1, 4, 7, 11)]) == 26)
[1] TRUE

all(rowSums(Lucky26[, c(8, 9, 10, 11)]) == 26)
[1] TRUE

all(rowSums(Lucky26[, c(2, 3, 4, 5)]) == 26)
[1] TRUE

all(rowSums(Lucky26[, c(2, 6, 9, 12)]) == 26)
[1] TRUE

all(rowSums(Lucky26[, c(5, 7, 10, 12)]) == 26)
[1] TRUE

* আমি এর লেখকRcppAlgos


6

জন্য , দুর্দান্ত। দুর্ভাগ্যক্রমে, 12 টি ক্ষেত্রের সাথে 479 মিলিয়ন সম্ভাবনা রয়েছে যার অর্থ বেশিরভাগ লোকের জন্য অত্যধিক স্মৃতি গ্রহণ করে:

library(RcppAlgos)
elements <- 12
permuteGeneral(elements, elements)
#> Error: cannot allocate vector of size 21.4 Gb

কিছু বিকল্প আছে।

  1. আদেশের নমুনা নিন। অর্থ, 479 মিলিয়ন এর পরিবর্তে 1 মিলিয়ন করুন। এটি করতে, আপনি ব্যবহার করতে পারেন permuteSample(12, 12, n = 1e6)। তিনি 479 মিলিয়ন অনুমানের নমুনা ব্যতীত কিছুটা অনুরূপ পদ্ধতির জন্য @ জোসেফউডের উত্তর দেখুন;)

  2. সৃষ্টির মূল্যায়ন করতে একটি লুপ তৈরি করুন। এটি স্মৃতি সংরক্ষণ করে কারণ আপনি কেবল সঠিক ফলাফলগুলি ফিরতে ফাংশনটি তৈরি করবেন।

  3. একটি ভিন্ন অ্যালগরিদম নিয়ে সমস্যাটি দেখান। আমি এই বিকল্পটিতে ফোকাস করব।

নতুন অ্যালগরিদম ডাব্লু / সীমাবদ্ধতা

ভাগ্যবান তারা 26 এ

বিভাগগুলি 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

ভাগ্যবান তারা সমাধান আর পরিসংখ্যান


এই সম্পর্কে ভাল উপায়। ধন্যবাদ.
মরুভূমি 0

1
আমি ইতিমধ্যে +1 করেছি, আশা করি আমি আরও দিতে পারতাম। এটি আমার ধারণা ছিল তবে আমার কোডটি খুব অগোছালো হয়ে গেল। সুন্দর জিনিস!
জোসেফ উড

1
এছাড়াও, পূর্ণসংখ্যার পার্টিশনগুলি (বা আমাদের ক্ষেত্রে রচনাগুলি) ছাড়াও, আমি গ্রাফ / নেটওয়ার্ক পদ্ধতির সাহায্যে বিনোদন দিয়েছি। এখানে অবশ্যই একটি গ্রাফ উপাদান রয়েছে তবে আবার এটির সাথে আমি কোনও মাথা তৈরি করতে সক্ষম হইনি। আমি মনে করি কোনওভাবে গ্রাফের সাথে পূর্ণসংখ্যার রচনাগুলি ব্যবহার করা আপনার পদ্ধতির পরবর্তী স্তরে যেতে পারে।
জোসেফ উড

3

এখানে চিত্র বর্ণনা লিখুন

ছোট্ট ফেলার সমাধান এখানে:

numbersToDrawnFrom = 1:12
bling=0

while(T==T){

  bling=bling+1
  x=sample(numbersToDrawnFrom,12,replace = F)

  A<-x[1]+x[2]+x[3]+x[4] == 26
  B<-x[4]+x[5]+x[6]+x[7] == 26
  C<-x[7] + x[8] + x[9] + x[1] == 26
  D<-x[10] + x[2] + x[9] + x[11] == 26
  E<-x[10] + x[3] + x[5] + x[12] == 26
  F1<-x[12] + x[6] + x[8] + x[11] == 26

  vectorTrue <- c(A,B,C,D,E,F1)

  if(min(vectorTrue)==1){break}
  if(bling == 1000000){break}

}

x
vectorTrue

"আমি আমার ছেলেকে দেখানোর চেষ্টা করছি যে কোনও কোড দ্বারা উত্থাপিত কোনও সমস্যা সমাধানের জন্য কীভাবে কোডিং ব্যবহার করা যেতে পারে এবং এটি কীভাবে বড় ডেটা পরিচালনা করে তা দেখে।" -> হ্যাঁ প্রত্যাশার মতো কমপক্ষে 1 টি সমাধান রয়েছে। তবে, ডেটা পুনরায় চালিয়ে আরও সমাধানের সন্ধান করা যেতে পারে।
হোর্হে লোপেজ

এটি সমাধানের দ্রুত সমাধান - অনেক ধন্যবাদ!
ডেজার্টপ্রজেক্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.