2012-04-02 13 views
17

'da nasıl oluşturulduğunu kontrol etme Haskell'deki alt set toplamı problemine bir çözüm bulmak için bir algoritma yazdım. İmza, bunu sınamak için iyi bir uygun gibi görünüyor.Test verilerinin QuickCheck

prop_sumEqualsS l s = case subsetSum l s of 
         Just solution -> (sum solution) == s 
         Nothing  -> True 

sorun algoritması oldukça yoğun hesaplama gerektiren ve büyük girdi listeleri ile 100 testleri çalışırken çalıştırmak için yaş alır olmasıdır: Örneğin burada ben kontrol edebilir özelliklerinden biridir.

QuickCheck 1 ile denedim ve hızlı bir şekilde çalıştı, ancak test için kullanılan veri kümeleri çok küçüktü. QuickCheck 2'ye geçtikten sonra karşı problem gibi görünüyor. QC için a manual var, ancak eski görünüyor (tarih bilgisi yok) ve QC2 için hala ne kadar olduğunu bilmiyorum. A Tutorial, Haskell Wiki'de mevcut, ancak çok fazla ayrıntı yok, sadece Arbitrary modelinde birkaç kelime var. QuickCheck 2 hangi değişiklikler

  • o kadar çok yavaş QuickCheck fazlalaşması yapmak:

    Yani iki sorum var?

  • Veri kümelerinin oluşturulmasının, belirli bir sınama için kullanışlı hale getirilmesinin en iyi yolu nedir?

Düzenleme: Ben QuickCheck 2 olduğunu tanıttığı -10000 ile 10000

+1

Kişisel sorulara QuickCheck bağlamında için biraz belirsiz görünüyor; belki bunun yerine genel bir test sorusu sormak daha iyi olur. Ancak şu anki yaklaşımınızla ilgili bir kaç problem var: çözümün aslında bir alt küme olduğunu kontrol etmeyecek, ya da işlev Hiçbir şey döndürmezse o zaman aslında çözüm yok. – gatoatigrado

+0

@gatoatigrado Özellik sadece bir örnekti. Çözümün bir alt kümenin başka bir mülke ait olduğunu kontrol ediyorum. Yanlış mıyım? Hiçbir şey iade edilmediğinde, başka bir algoritma ile sorunu tekrar çözmekten başka bir çözüm olmadığını kontrol etmenin kolay bir yolunu görmüyorum. Bu biraz gereksiz görünüyor. – Antoine

+0

http://stackoverflow.com/questions/10712373/cookbook-for-converting-from-quickcheck1-to-quickcheck2 – gliptak

cevap

25

Bir şey arasındaki tamsayılar içeren, 0 ila 100 den bir liste boyutu ile benim çözüm test etmek istiyorum, daha spesifik olmak gerekirse kaynağının verimsizliği shrink fonksiyonudur. Bir özellik başarısız olursa, , daha düşük test değerlerine adaylar veren küçültme işlevi çağrılır ve bunlar, özelliğin başarısız olduğu daha küçük bir değere sahip olana kadar daraltılır. Ancak, özellikler başarısız olduğunda bu yalnızca olur. listeleri için keyfi örneğin

değişiklikler version 1 ve version 2 arasında çok değişmedi. Farklılık ifadeler içeriyor, sürüm 1, vector kullanıyor ve sürüm 2, liste anlaşmasını kullanıyor, ancak daha sonra vector, sıralı çağrıların rasgele aramalarının tam listesiyle uygulanmaktadır.

Her iki uygulamada, boyut parametresi kullanılmıştır. QuickCheck 1'de, oluşturulan bir değer boyutunda varsayılan div n 2 + 3, burada n testin numarasıdır. HızlıKontrol 2, maksimum boyutu ve testlerin sayısı yapılandırılmış başka bir yaklaşımı kullanır. Test boyutları bu aralıkta dağıtılacak ve test sayısında doğrusal olarak büyüyecektir (quickCheckWithResult numaralı telefondan computeSize'). Bu, 100 testin ve maksimum boyutun varsayılan ayarıyla, QuickCheck 1'den gelen maksimum , (div 100 2 + 3) = 53 ve QuickCheck 2 ile 100 olacaktır.Sonra) muazzam tabii uzunluğu 50 ile 100 kutunun bir liste arasında çalışma süresi farkı ; subsetine toplamı olarak

muhtemelen bir üstel algoritma var NP-tamamlandı. Anlaşılır şekilde test edilecek küçük listeler istersiniz. İki adet seçeneğiniz var: yeni bir veri tipi oluştur (tercihen newtype ile) veya 'u bağımsız bir jeneratör yapın ve forAll'u kullanın. newtype'u kullanarak 'u da değerlerin daraltılması gerektiğini belirtebilirsiniz.

newtype SmallIntList = SmallIntList [Int] deriving (Eq,Show) 

instance Arbitrary SmallIntList where 
    arbitrary = sized $ \s -> do 
       n <- choose (0,s `min` 50) 
       xs <- vectorOf n (choose (-10000,10000)) 
       return (SmallIntList xs) 
    shrink (SmallIntList xs) = map SmallIntList (shrink xs) 

Bu Arbitrary örneği 50 elemanlarından daha listeleri artık yapmaz: Bu newtype yaklaşımı kullanarak bir örnek uygulamasıdır. Öğeler, boyut parametresini kullanmaz, bu nedenle her zaman [-10000,10000] aralığındadır, bu nedenle iyileştirme için bir yer vardır. shrink işlevi yalnızca shrink listelerini ve Int s sayfalarını kullanır.

sadece SmallIntList gibi bir argüman kullanın mülkünüzle bu örneğini kullanmak için:

prop_sumEqualsS (SmallIntList l) s = case subsetSum l s of 
             ...