स्पोइलर्स: मैं http://www.spoj.pl/problems/KNAPSACK/ पर काम कर रहा हूं इसलिए यदि आप संभव समाधान खराब नहीं करना चाहते हैं तो देखें।एसपीओजे के लिए यह ज्ञात डीपी तालिका कितनी धीमी है?
बॉयलरप्लेट:
type Item = (Weight, Value)
type Weight = Int
type Value = Int
weight :: Item -> Weight
weight = fst
value :: Item -> Value
value = snd
makeItem :: [String] -> Item
makeItem [w, v] = (read w, read v)
और प्राथमिक कार्य:
import Data.Sequence (index, fromList)
import Data.MemoCombinators (memo2, integral)
main = interact knapsackStr
knapsackStr :: String -> String
knapsackStr str = show $ knapsack items capacity numItems
where [capacity, numItems] = map read . words $ head ls
ls = lines str
items = map (makeItem . words) $ take numItems $ tail ls
कुछ प्रकार के और सहायकों मंच तैयार करने के लिए
knapsack :: [Item] -> Weight -> Int -> Value
knapsack itemsList = go
where go = memo2 integral integral knapsack'
items = fromList $ (0,0):itemsList
knapsack' 0 _ = 0
knapsack' _ 0 = 0
knapsack' w i | wi > w = exclude
| otherwise = max exclude include
where wi = weight item
vi = value item
item = items `index` i
exclude = go w (i-1)
include = go (w-wi) (i-1) + vi
और इस कोड काम करता है; मैंने एसपीओजे नमूना परीक्षण मामले में प्लगिंग करने की कोशिश की है और यह सही परिणाम उत्पन्न करता है। लेकिन जब मैं एसपीओजे को यह समाधान प्रस्तुत करता हूं (ल्यूक पामर के मेमोकॉम्बिनेटर्स को आयात करने के बजाय, मैं बस आवश्यक स्रोतों को प्रतिलिपि स्रोत में कॉपी और पेस्ट करता हूं), यह समय सीमा से अधिक है। =/
मुझे समझ में नहीं आता क्यों; 0-0-1 knapsack करने के लिए एक कुशल तरीका के बारे में, और मुझे काफी आश्वस्त है कि यह जितना तेज़ हो जाता है: एक ज्ञापन कार्य जो केवल उप-प्रविष्टियों की गणना करेगा जो इसे पूरी तरह से करने के लिए आवश्यक हैं सही परिणाम क्या मैंने किसी भी तरह से यादों को गड़बड़ कर दिया? क्या इस कोड में धीमा बिंदु है कि मुझे याद आ रही है? एसपीओजे सिर्फ हास्केल के खिलाफ पक्षपातपूर्ण है?
मैंने जमा करने के शीर्ष पर {-# OPTIONS_GHC -O2 #-}
भी रखा, लेकिन हां, इससे मदद नहीं मिली। मैंने एक समान समाधान की कोशिश की है जो Sequence
एस की 2 डी सरणी का उपयोग करती है, लेकिन इसे धीमी गति से अस्वीकार कर दिया गया था।
क्या आपने प्रोफाइलिंग करने का प्रयास किया है? आम तौर पर, मुझे नहीं पता है कि ज्ञापन यह है कि अधिकांश कार्यों के लिए बड़ी सहायता। साथ ही, अनुक्रम का उपयोग करने से यहां बहुत मदद नहीं मिलती है, शायद इसके बजाय 'मानचित्र'? – ivanm
क्या आप हमें प्रदान की गई memotries के आवश्यक बिट्स के साथ पूरा कोड दिखा सकते हैं? इससे समस्या का निदान करना आसान हो जाएगा। –
'इंडेक्स 'ऑपरेशन' ओ (लॉग (मिनट (i, n-i))) '(हैडॉक के अनुसार) है। शायद आपको एक ऐरे या वेक्टर का उपयोग करना चाहिए। –