2013-12-08 100 views
0

目標:生成一組矩形框並將它們堆疊到10x10網格上。我的功能getCoordinates會生成numBoxes隨機大小的框,整數長度介於1和10之間。變量gridTops會跟蹤10x10網格中每個單元佔用的最大高度。該函數返回一個兩元素列表,其中包含一個帶有堆疊框的座標的矩陣和gridTops如何讓此R代碼更快運行

getCoordinates<-function(numBoxes){ 
    # Generates numBoxes random sized boxes with integer dimensions between 1 and 10. 
    # Stacks them and returns results 
    boxes<-data.frame(boxId=1:numBoxes, 
        xDim=sample(10,numBoxes, replace=TRUE), 
        yDim=sample(10,numBoxes, replace=TRUE), 
        zDim=sample(10,numBoxes, replace=TRUE)) 
    gridTops<-matrix(0,nrow=10,ncol=10) 
    coordinates<-matrix(nrow=nrow(boxes), 
         ncol=6, 
         dimnames=list(boxes$boxId,c("x1","y1","z1","x8","y8","z8"))) 
    for(i in 1:nrow(boxes)){ 
    mylist<-addBox(boxes[i,], gridTops); 
    coordinates[i,]<-mylist[["coordinates"]]; 
    gridTops<-mylist[["gridTops"]]; 
    } 
    return(list(boxes=boxes, coordinates=coordinates)); 
} 

addBox<-function(boxDimensions, gridTops){ 
    #Returns a list of coordinates and the updated gridTops matrix 
    xd<-boxDimensions$xDim 
    yd<-boxDimensions$yDim 
    zd<-boxDimensions$zDim 
    x1<-0 
    y1<-0 
    z1<-max(gridTops[1:xd,1:yd]) 
    gridTops[1:xd,1:yd]<-(z1+zd) 
    coordinates<-c(x1,y1,z1,x1+xd,y1+yd,z1+zd) 
    return(list(coordinates=coordinates,gridTops=gridTops)) 
} 

舉個例子,

test<-getCoordinates(5) 
test[["boxes"]] 
    boxId xDim yDim zDim 
1  1 5 2 4 
2  2 9 1 4 
3  3 1 7 7 
4  4 10 6 1 
5  5 5 8 10 
test[["coordinates"]] 
    x1 y1 z1 x2 y2 z2 
1 0 0 0 5 2 4 
2 0 0 4 9 1 8 
3 0 0 8 1 7 15 
4 0 0 15 10 6 16 
5 0 0 16 5 8 26 

正如你看到的,我的堆放箱子的方法只是把一個在頂部的另一個上的一個角落(X = 0,Y = 0)細胞。很簡單,但要堆疊10000個盒子需要很長時間。例如

system.time(getCoordinates(10000)) 
user system elapsed 
2.755 0.414 3.169 

我認爲我的for循環正在放慢速度,但我不知道如何在這種情況下應用apply函數。我如何加速這件事?

編輯:方法addBox可能會改變。正如我所提到的,它只是將一個盒子放在下一個盒子上。這是一種天真的包裝算法,但我爲了說明的目的而編寫它。

+0

當我運行你的代碼,然後' test <-getCoordinates(5)',test是一個座標矩陣,而不是一個列表(??)。 – jlhoward

+0

@jlhoward哎呀!看到我編輯的代碼。對於那個很抱歉。 – Ben

回答

1

boxesdata.frame更改爲matrix對我來說可以大大加快速度。

我改變

boxes<-data.frame(

boxes <- cbind(

和編輯您在兩個函數訪問盒的地方,從去:

R>system.time(getCoordinates(10000)) 
    user system elapsed 
    1.926 0.000 1.941 
R>getCoordinates <- edit(getCoordinates) 
R>addBox <- edit(addBox) 
R>system.time(getCoordinates(10000)) 
    user system elapsed 
    0.356 0.002 0.362 
+0

你是如何通過'boxes'矩陣循環的?你是否像我一樣使用循環? – Ben

+0

是的,我只*將箱子改爲矩陣。 –

+1

你還需要將'boxes $ boxId'改成'boxes [,「boxId」]''。 – flodel