2011-07-26 20 views
10

Ben bir böl ve yönet algoritması üzerinde çalışıyorum (aslında, bir dizi giriş noktasına eğri uydurma yapan). 'Böl' kısmı için, her nokta için bir hata teriminin hesaplanması gerekiyor ve eğer hata belirli bir eşiği aşarsa, eğriyi o noktada bölmek ve girişin sol ve sağ bölümlerini ayrı ayrı işlemek istiyorum. Basit bir döngü hile yapar; ama şu anki bölümün ortasında başlamam ve dışarıdan çalışmak benim için avantajlı olurdu. (Netleştirmek gerekirse: hatası çok büyük olan bir noktayı bulursam, yinelemeli olarak sol ve sağ bölümler için ayrı eğriler ararım ve üretirim - eğer tüm noktalar eşiğin içindeyse, benim eğrime uyuyor ve dönüyorum). yakın başlayarak diğer bir deyişleAlgoritma, ortadan dışa doğru bir dizi üzerinden mi geçecek?

int steps = (endIndex+1-startIndex); 
int i = (startIndex+endIndex)>>1; 
int stepdir = 1; 
for(int q=0; q<steps; q++, i+=stepdir*q, stepdir=-stepdir) 
{ 
    // test point i here and return early if error exceeds threshold 
} 

: Baş-çizilmemesi biraz sonra

, ben (noktalar bir dizi vardır ve mevcut bölüm startIndex gelen kapsayıcı endIndex etmektir) bu geldi Orta, bir endeks ileri, iki geri, üç ileri, dört geri ... Çalışır, ve eminim ki bu verimli, ama bunu yapmak için daha temiz bir yol olmalı, özellikle, ben sona erdi güncelleme dilindeki ifadelerin sırayla değerlendirildiğinden emin olmak için Java dil özelliklerini kontrol etmek zorunda kalmadan (C/C++'da olduğu gibi bir sıra operatörü olmasa bile).

Herhangi bir fikir için minnetle teşekkür ederiz. Daha temiz bir yolu var mı?

+0

bir özyinelemeli işlevinin bir parçası olarak bu döngüyü kullanıyor musunuz? Örneğin, her bölme için birbirini ayırın ve tekrarlı olarak arayın. –

+0

Evet ... açıklığa kavuşturmak için soruyu düzenledik. Son sonuç, bazı kaynak noktalarında birleştirilmiş 'basit' eğriler ve aradakilere 'yeterince yakın'. –

cevap

14

Bu

for (int q=0; q < steps; q++) { 

    int index = i + (q% 2 == 0 ? q/2 : -(q/2+1)); //index lookup here 
} 

Düzenleme imho daha okunabilir olacaktır: senin aşırı yanılma denetleyicisi (örneğin bir işlev çağrısı) basitse indeks araması bir hata fark

+0

Anlaşıldı. Bu, her dizinin tam olarak bir kez ziyaret edildiğini ve tüm dizinin kaplandığını daha açık hale getirir. Teşekkürler. –

+0

bu iki kere sıfır ziyaret etmiyor mu? – phkahler

+0

q == 1 ise index = i + - (0 + 1) olur. q == 2 ise index = i + (1) olur. Daha net hale getirmek için örneğe köşeli parantezler ekleyeceğim – jontro

1

, en net şey etmektir yazma:

int mid = npoints/2; 
for (int i = 0; i <= mid; i++) { 
    if(excess_error(mid + i + 1)) { 
      // divide at mid + i + 1 
    } else if excess_error(mid - i) { 
      // divide at mid - i 
    } 
} 

Yine "bölmek xyz de" kod bir işlev çağrısı olmalıdır, yoksa & yapıştırılan kod kesilmiş olsun.

(ı köşe durumlarda dikkatle düşünce değil ve ben == orta, ama resmi olsun off-by-tek hataları, bu yüzden dikkatli olun.)

+0

Çok büyük bir hata bulduğumda, döngüden çıkıp iki yarıyı tekrar tekrar giriyorum ... böylece 'böl' bölümü oldukça fazla bölünüyor nokta değişkeni ve döngüden ayrılır. Daha sonraki raporlama için hata hesaplamasının sonuçlarını saklıyorum; Bu nedenle, genel davranışın işlev çağrısı içinde uygulanmasının gerektiğini belirtmek gerekir. –

+0

Tamam, böylece kaydetme noktası ve mola da oldukça basittir, kod tekrarı miktarı neredeyse bir işlev çağrısı kadar az olacaktır. –

0

İşte herkes için daha genel bir çözüm Bu, rastgele bir noktadan dışarı doğru arama yapmak zorundadır (bu örnekte, uzunluk 7 dizisinde [6] hücresinde).

int arraySize = 7; 
int start = 6; 

for (int i=0; i < arraySize; i++) { 
    int index = (start+((i%2==0)?i/2:arraySize-(i+1)/2))%arraySize; 
    print(index+","); 
} 
exit(); 

Baskılar 6,5,0,4,1,3,2,

İlgili konular