2017-02-14 77 views
0

如何強制遞歸函數在運行時產生幀?如何強制遞歸函數生成跳過幀?

我試圖把屈服函數的遞歸函數的不同階段。

我不明白髮生了什麼,因爲如果條件印刷品時,每1000個遞歸被忽略,它只是產量和打印大約每100萬個遞歸。應該被拾取的打印命令的90%被代碼忽略並且不出現。 運行時每隔1-2分鐘產生一次,並一次打印十幾條語句。

這是我已成功地編寫代碼的最快的版本;如果我向上或向下更改yield單詞,運行時有時會完全凍結,10分鐘內沒有任何反應。

爲什麼它凍結,我該如何改變呢?

//A working 3D floodfill function that reads and writes a boolean voxel array: 

private var maxAbort = 1000000000; 

function boundary(x:int, y:int, z:int): IEnumerator //floodfill algo 
{ 
    if (read3DboolArray(x,y,z)==false && bcnt<maxAbort){//pprevent stackoverflow with limit FASTER 
     if (x >= 0 && x < bsizex && y >= 0 && y < bsizey && z >= 0 && z < bsizez) 
     {   

      write3DboolArray(x,y,z,true); 


      boundary(x+1,y,z); 
      boundary(x-1,y,z);  yield WaitForFixedUpdate(); 
      boundary(x,y+1,z); 
      boundary(x,y-1,z); // yield WaitForFixedUpdate(); 
      boundary(x,y,z+1); 
      boundary(x,y,z-1); 
     } 

     if (bcnt % 1000== 0)//mark new start if ended this recursion run 
     { 
      print(bcnt+ " ------  " + 
       (Time.realtimeSinceStartup-tt)); 
      bcnt+=1; 

      yield WaitForFixedUpdate(); 
     } 
    } else return; 
} 

它使用Unity3D的MonoDevelop中運行時它是.NET框架2.0

+0

我用一種比通用堆棧更好的方法解決了這個問題,這裏的結果是https://unity3dmc.blogspot.fr/2017/02/ultimate-3d-floodfill-scanline.html –

回答

2

在一個方法使用產率的叉基本上接通方法轉化爲一個迭代的構造函數。爲了讓迭代器實際上做一些有意義的事情,你實際上需要迭代它。

boundary(x+1,y,z); 
    boundary(x-1,y,z);  yield WaitForFixedUpdate(); 
    boundary(x,y+1,z); 
    boundary(x,y-1,z); // yield WaitForFixedUpdate(); 
    boundary(x,y,z+1); 
    boundary(x,y,z-1); 

這基本上只是創建了幾個普查員,然後拋出他們離開。爲了使遞歸良率起作用,您必須將所有結果返回到初始呼叫站點。

這樣做可以用產量和協同程序對這種工作量似乎非常低效。我建議要麼試圖重塑算法是迭代(by using a stack for example,這也將有明顯的堆棧溢出問題的幫助),或卸載到一個單獨的工作線程這一點。

+0

謝謝,我發現了一些很好的提示那個迭代版本。可能會在某個階段實施。目前遞歸版本可以做60mn體素,我只是運行一個600mn體素版本,只是速度很慢。當我寫它時,會有更好的3D填充碼。 –