AMcoder - javascript, python, java, html, php, sql

Ընտրեք համակցությունների ենթաբազմություն

Ենթադրենք, որ ես ունեմ 20 X 5 մատրիցա, ես կցանկանայի ընտրել մատրիցի ենթաբազմությունները և դրանցով կատարել որոշակի հաշվարկ: Հետագայում ենթադրենք, որ յուրաքանչյուր ենթամատրիցան 7 X 5 է: Ես, իհարկե, կարող էի անել

ncomb <- combn(20, 7)

որն ինձ տալիս է 7 տողերի ինդեքսների բոլոր հնարավոր համակցությունները, և ես կարող եմ դրանք օգտագործել ենթամատրիցներ ստանալու համար: Բայց փոքր, 20 X 5 մատրիցով, արդեն կա 77520 հնարավոր համակցություն: Այսպիսով, ես կուզենայի փոխարենը պատահականորեն ընտրել որոշ համակցություններ, օրինակ՝ դրանցից 5000-ը:

Հնարավորություններից մեկը հետևյալն է.

ncomb <- combn(20, 7)
ncombsub <- ncomb[, sample(77520, 5000)]

Այլ կերպ ասած, ես ստանում եմ բոլոր հնարավոր համակցությունները, իսկ հետո պատահականորեն ընտրում եմ համակցություններից միայն 5000-ը: Բայց ես պատկերացնում եմ, որ խնդրահարույց կլիներ հաշվարկել բոլոր հնարավոր համակցությունները, եթե ես ունենայի ավելի մեծ մատրիցա, ասենք, 100 X 7:

Ուստի ես զարմանում եմ, թե արդյոք կա՞ մի տարբերակ ստանալ համակցությունների ենթաբազմություններ՝ առանց նախապես ձեռք բերելու բոլոր հնարավոր համակցությունները:

17.08.2013

  • Այո, ես կարծում եմ, որ դա հնարավոր է՝ փոփոխելով combn-ը կամ գրելով ձեր սեփական ֆունկցիան (որը կարող է ավելի հեշտ լինել): Դրա համար ալգորիթմ մշակելը և դրա իրագործումը չպետք է դժվար լինի: 17.08.2013
  • Դուք կարող եք տեսնել համապատասխան գրառումը այստեղ 17.08.2013
  • @Roland Ես ի վերջո փոփոխեցի combn()ը, ինչպես դուք առաջարկեցիք: Լավ է աշխատում: 18.08.2013

Պատասխանները:


1

Ձեր մոտեցումը.

op <- function(){
    ncomb <- combn(20, 7)
    ncombsub <- ncomb[, sample(choose(20,7), 5000)]
    return(ncombsub)
}

Տարբեր ռազմավարություն, որը պարզապես նմուշառում է յոթ տող սկզբնական մատրիցից 5000 անգամ (ցանկացած կրկնօրինակ նմուշները փոխարինելով նոր նմուշով մինչև 5000 եզակի տողերի համակցություններ գտնվեն).

me <- function(){
  rowsample <- replicate(5000,sort(sample(1:20,7,FALSE)),simplify=FALSE)
  while(length(unique(rowsample))<5000){
     rowsample <- unique(rowsample)
     rowsample <- c(rowsample,
                    replicate(5000-length(rowsample),
                              sort(sample(1:20,7,FALSE)),simplify=FALSE))
  }
  return(do.call(cbind,rowsample))
}

Սա պետք է լինի ավելի արդյունավետ, քանի որ դա ձեզ թույլ չի տալիս նախ հաշվարկել բոլոր համակցությունները, որոնք թանկ կլինեն, քանի որ մատրիցը մեծանում է:

Եվ այնուամենայնիվ, որոշ չափորոշիչներ ցույց են տալիս, որ դա այդպես չէ: Առնվազն այս մատրիցով.

library(microbenchmark)
microbenchmark(op(),me())

Unit: milliseconds
 expr      min       lq   median      uq      max neval
 op() 184.5998 201.9861 206.3408 241.430 299.9245   100
 me() 411.7213 422.9740 429.4767 474.047 490.3177   100
17.08.2013
  • Մի երկու հարց. Որպեսզի ձեր կոդը աշխատի, կարծում եմ, որ դուք պետք է նաև տեսակավորեք յուրաքանչյուր սյունակ մինչև while հանգույցը, այսինքն՝ տեսակավորեք ինդեքսների յուրաքանչյուր նմուշ: Հակառակ դեպքում, unique()-ը չի աշխատի: Երկրորդ խնդիրն, իմ կարծիքով, այն է, որ unique()MARGIN արգումենտը պետք է սահմանվի 2-ի (կանխադրված՝ 1 է): Նաև length(unique(rowsample))-ի փոխարեն այն պետք է լինի ncol(unique(rowsample)): Քանի որ length-ը ձեզ տալիս է matrix-ում պարունակվող տարրերի ընդհանուր թիվը, այլ ոչ թե սյունակների քանակը (իմ դեպքում յուրաքանչյուր սյունակ նմուշ է, ուստի 5000 սյունակները ինդեքսների 5000 նմուշ են): 18.08.2013
  • @Alex-ը որոշ փոփոխություններ կատարեց (մտածում էր replicate վերադարձնել ցուցակը, ոչ թե մատրիցա): Պարզվում է, որ դա այնքան էլ արդյունավետ չէ, որքան ձեր սկզբնական լուծումը: Եվ, եթե թույլ եք տալիս replicate-ին պարզեցնել մատրիցը, դա ավելի դանդաղ է: 18.08.2013
  • Ես ի վերջո փոփոխեցի բնօրինակ combn() ֆունկցիան և բայթ-կազմեցի այն: Լավ է աշխատում։ Բայց, այնուամենայնիվ, շնորհակալություն այս լուծման համար, կարծում եմ, որ ձեր ռազմավարությունը կարող է օգտակար լինել որոշ այլ բաների համար, որոնց վրա ես աշխատում եմ: 18.08.2013

  • 2

    Ես ավարտեցի այն, ինչ առաջարկեց @Roland-ը՝ փոփոխելով combn()-ը և բայթ-կոմպիլյացիայի ենթարկելով կոդը.

    combn_sub <- function (x, m, nset = 5000, seed=123, simplify = TRUE, ...) {
        stopifnot(length(m) == 1L)
        if (m < 0) 
            stop("m < 0", domain = NA)
        if (is.numeric(x) && length(x) == 1L && x > 0 && trunc(x) == 
            x) 
            x <- seq_len(x)
        n <- length(x)
        if (n < m) 
            stop("n < m", domain = NA)
        m <- as.integer(m)
        e <- 0
        h <- m
        a <- seq_len(m)
        len.r <- length(r <-  x[a] )
        count <- as.integer(round(choose(n, m)))
        if( count < nset ) nset <- count
        dim.use <- c(m, nset)       
    
        ##-----MOD 1: Change the output matrix size--------------
        out <- matrix(r, nrow = len.r, ncol = nset) 
    
        if (m > 0) {
            i <- 2L
            nmmp1 <- n - m + 1L
    
            ##----MOD 2: Select a subset of indices
            set.seed(seed)
            samp <- sort(c(1, sample( 2:count, nset - 1 )))  
    
            ##----MOD 3: Start a counter.
            counter <- 2L    
    
            while (a[1L] != nmmp1 ) {
                if (e < n - h) {
                    h <- 1L
                    e <- a[m]
                    j <- 1L
                }
                else {
                    e <- a[m - h]
                    h <- h + 1L
                    j <- 1L:h
                }
                a[m - h + j] <- e + j
    
                #-----MOD 4: Whenever the counter matches an index in samp, 
                #a combination of row indices is produced and stored in the matrix `out`
                if(samp[i] == counter){ 
                    out[, i] <- x[a]
                    if( i == nset ) break
                    i <- i + 1L
                }
                #-----Increase the counter by 1 for each iteration of the while-loop
                counter <- counter + 1L
            }
        }
        array(out, dim.use)
    }
    
    library("compiler")
    comb_sub <- cmpfun(comb_sub)
    
    18.08.2013
    Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..