2010-10-07 9 views
5

मेरे पास 0.133 से 0.005 तक (लेकिन ज्यादातर छोटी तरफ) 43 से 50 संख्याओं का संग्रह है। मैं, खोजने के लिए यदि संभव हो तो चाहते हैं, सभी संयोजनों एल और आर के बीच एक योग है, जो एक साथ बहुत करीब हैं। *बिन-पैकिंग (या knapsack?) समस्या

जानवर बल विधि, 2 2 को कदम उठा लेता है जो प्रतिसाद नहीं व्यवहार्य नहीं है यहां उपयोग करने के लिए एक अच्छी विधि क्या है?

संपादित करें: संयोजनों का उपयोग गणना और त्याग में किया जाएगा। (यदि आप कोड लिख रहे हैं, तो आप मान सकते हैं कि वे बस आउटपुट हैं; मैं आवश्यकतानुसार संशोधित करूंगा।) संयोजनों की संख्या स्मृति में पकड़ने के लिए संभवतः बहुत बड़ी होगी।

* एल = 0.5877866649021190081897311406, आर = 0.5918521703507438353981412820।

+0

(2^50) नैनोसेकंड = 13.0312489 दिन –

+0

हां। प्रत्येक संयोजन के लिए मैं संख्या पर गणना करूंगा और इसे छोड़ दूंगा। – Charles

उत्तर

1

के लिए संभव नहीं हो सकता मूल विचार इसे एक पूर्णांक knapsack समस्या में परिवर्तित करना है (जो आसान है)।

एक छोटी वास्तविक संख्या e और अपनी मूल समस्या में गोल संख्या k*e के साथ पूर्णांक k के साथ प्रतिनिधित्व करने योग्य चुनें। छोटे e, पूर्णांक पूर्णांक (दक्षता व्यापार) होगा लेकिन संशोधित समस्या का समाधान आपके मूल के करीब होगा। एक e=d/(4*43) जहां डी आपके लक्ष्य अंतराल की चौड़ाई पर्याप्त छोटा होना चाहिए।

यदि संशोधित समस्या में आपके लक्षित अंतराल के मध्य (e से गोलाकार) के बीच एक सटीक समाधान है, तो मूल समस्या अंतराल के भीतर कहीं कहीं है।

+1

एक समाधान ढूंढना एक नापसंद समस्या है, लेकिन सवाल उन सभी को खोजने के लिए कहता है। – Aaron

+0

सहमत हैं, लेकिन अगर वास्तव में बहुत से लोग हैं (औसतन वहां नहीं होंगे), तो कम से कम आप उन्हें प्रभावी ढंग से उत्पन्न कर सकते हैं। –

1

आपने हमें पर्याप्त जानकारी नहीं दी है। लेकिन ऐसा लगता है कि यदि आप वास्तव में हर संभावित संयोजन को आउटपुट करना चाहते हैं तो आप परेशानी में हैं। उदाहरण के लिए, आपने जो बताया है उसके अनुरूप, ये है कि प्रत्येक नंबर ~ .027 है। यदि यह मामला है, तो आपके मानदंड को पूरा करने वाले तत्वों के आधे हिस्से का संग्रह। लेकिन 43 ऐसे 21 सेट हैं, जिसका मतलब है कि आपको कम से कम 1052049481860 सेट आउटपुट करना होगा। (व्यवहार्य होने के लिए बहुत से लोग)

निश्चित रूप से चलने का समय आवश्यक आउटपुट की लंबाई से बेहतर नहीं होगा।

+1

+1 यह एक वैध प्रमाण है। –

+0

और 50 का चयन 256 ट्रिलियन है ... :-) – Aaron

+0

लेकिन यदि आप एक एल्गोरिदम के साथ आ सकते हैं जो ओ (आउटपुट का आकार) है, तो केवल कुछ छोटी संख्या में समाधान सेट के साथ समस्या हो सकती है पूरी तरह से पता लगाने योग्य। जो अच्छा होगा। यदि इनपुट एक बहुत बड़े आउटपुट की मांग करता है, तो निश्चित रूप से आप सही हैं कि इसमें काफी समय लगेगा, लेकिन तर्कसंगत है कि यह कॉलर की समस्या है। –

0

वास्तव में, वहाँ इस के चारों ओर एक तेज तरीका है:

(अजगर)

sums_possible = [(0, [])] 
# sums_possible is an array of tuples like this: (number, numbers_that_yield_this_sum_array) 
for number in numbers: 
    sums_possible_for_this_number = [] 
    for sum in sums_possible: 
     sums_possible_for_this_number.insert((number + sum[0], sum[1] + [number])) 
    sums_possible = sums_possible + sums_possible_for_this_number 

results = [sum[1] for sum in sums_possible if sum[0]>=L and sum[1]<=R] 

इसके अलावा, हारून सही है, तो यह या आप

+0

यह अच्छा नहीं है क्योंकि sums_possible तेजी से बढ़ता है। –

+0

मुझे सभी संयोजनों को उत्पन्न करने की आवश्यकता है, लेकिन मैं उन्हें एक समय में स्मृति में नहीं रख सकता। कोड को गणना के रूप में संशोधित किया जा सकता है क्योंकि उनकी गणना की जाती है, केवल (कहें) 1 जीबी मेमोरी का उपयोग कर? – Charles

+0

आप कुछ छोटे सुधार कर सकते हैं, जैसे कि 'sums_possible = [योग में योग = यदि संभव है तो राशि <= R]' (पहले से बहुत अधिक रकम को हटा रहा है), लेकिन मुझे नहीं पता कि इसमें कितना सुधार होगा हो। इसके अलावा, मैं नहीं देख सकता कि क्या किया जा सकता है .. –