मुझे यकीन नहीं है कि आप जो चाहते हैं वह है - मुझे यकीन है कि यह आपके मन में नहीं था - लेकिन यदि यह उचित लगता है तो आप इसे आजमा सकते हैं।
मान लें कि इस समस्या के लिए आपके पास इष्टतम एल्गोरिदम है, और यह अंतिम पंक्ति से a <= d
पर अगली पंक्ति (ओं) रखता है। कहें कि यह b
लाइनें रखता है। हमारा लालची एल्गोरिदम निश्चित रूप से b
लाइनों से अधिक नहीं रखेगा (क्योंकि पहला मानदंड जितना संभव हो उतना कम जगह है), और यदि यह b
लाइनों को रखता है तो यह उन्हें c
a <= c <= d
के साथ दूरी पर रखेगा, क्योंकि यह तब तक लाइनों को रखता है मुमकिन।
लालची एल्गोरिथ्म क्या इष्टतम एल्गोरिथ्म किया भी नहीं किया है, तो निम्न तरीकों में से एक में मतभेद:
यह दूर ही या इससे कम लाइनों रखा। मान लीजिए कि इष्टतम एल्गोरिदम b'
लाइनों को अगले चरण में a'
पर दूरी पर चला गया था। फिर ये लाइनें a+a'
पर होगी और कुल में b+b'
लाइनें होंगी। लेकिन लालची एल्गोरिदम c' = (a+a') - c
चुनकर विस्थापन a+a'
पर b'
लाइनों को रखकर इस मामले में इष्टतम एल्गोरिदम की नकल कर सकता है। चूंकि c > a
और a' < d
, c' < d
और यह एक कानूनी प्लेसमेंट है।
यह कम लाइनों को एकसाथ करीब रखता है। यह मामला वास्तव में समस्याग्रस्त है। यह संभव है कि k
अनावश्यक लाइनों को रखें, यदि किसी प्लेसमेंट को कम से कम k
लाइनों की आवश्यकता होती है और सबसे दूर की आवश्यकता होती है, और छेद की व्यवस्था को चुना जाता है ताकि (उदा।) दूरी जो दूरी फैलती है वह d
का एक बहु है।
तो लालची एल्गोरिदम 2 मामले में काम नहीं करता है। हालांकि, यह अन्य मामलों में करता है। विशेष रूप से, पहले मामले में हमारा अवलोकन बहुत उपयोगी है: किसी भी दो प्लेसमेंट (distance, lines)
और (distance', lines')
के लिए, distance >= distance'
और lines <= lines'
, पहले प्लेसमेंट को हमेशा प्राथमिकता दी जानी चाहिए।
PlaceLines(start, stop)
// if we are close enough to the other edge,
// don't place any more lines.
if start + d >= stop then return ([], 0)
// see how many lines we can place at distance
// d from the last placed lines. no need to
// ever place more lines than this
nmax = min_lines_at_distance(start + d)
// see how that selection pans out by recursively
// seeing how line placement works after choosing
// nmax lines at distance d from the last lines.
optimal = PlaceLines(start + d, stop)
optimal[0] = [d] . optimal[0]
optimal[1] = nmax + optimal[1]
// we only need to try fewer lines, never more
for n = 1 to nmax do
// find the max displacement a from the last placed
// lines where we can place n lines.
a = max_distance_for_lines(start, stop, n)
if a is undefined then continue
// see how that choice pans out by placing
// the rest of the lines
candidate = PlaceLines(start + a, stop)
candidate[0] = [a] . candidate[0]
candidate[1] = n + candidate[1]
// replace the last best placement with the
// one we just tried, if it turned out to be
// better than the last
if candidate[1] < optimal[1] then
optimal = candidate
// return the best placement we found
return optimal
यह एक कैश (start, stop)
द्वारा अनुक्रमित में परिणाम (seq, lines)
डालकर Memoization द्वारा सुधार किया जा सकता: यह निम्नलिखित कलन विधि पता चलता है। इस तरह, हम पहचान सकते हैं कि जब हम असाइनमेंट की गणना करने की कोशिश कर रहे हैं जिसका पहले से मूल्यांकन किया जा सकता है। मैं उम्मीद करता हूं कि इस मामले में बहुत कुछ होगा, भले ही आप समस्या उदाहरणों के लिए मोटे या ठीक विघटन का उपयोग करें।
मुझे इस बारे में विवरण नहीं मिलता है कि max_lines_at_distance
और max_distance_for_lines
फ़ंक्शन कैसे काम कर सकते हैं, लेकिन शायद इन पर एक शब्द हो सकता है।
पहला आपको दिए गए विस्थापन पर बताता है कि ज्यामिति को फैलाने के लिए कितनी लाइनों की आवश्यकता है। यदि आपने अपनी ज्यामिति और रंगीन छेदों को काला रंग दिया है, तो इसका मतलब यह होगा कि संकेतित विस्थापन पर कोशिकाओं की पंक्ति को देखते हुए, समेकित ब्लैक लाइन सेगमेंट पर विचार करना और वहां से निर्धारित करना कि कितनी रेखाएं हैं।
दूसरा आपको बताता है कि लाइनों के दिए गए उम्मीदवार संख्या के लिए, वर्तमान स्थिति से अधिकतम दूरी जिस पर लाइनों की संख्या रखी जा सकती है। आप इसे अधिकतम दूरी बताकर इसे बेहतर बना सकते हैं जिस पर लाइनों की संख्या, या कम रखा जा सकता है।आप इस सुधार का उपयोग करते हैं, तो आप जिस दिशा में आप n
और पुनरावृत्ति कर रहे हैं रिवर्स सकता है:
- अगर
f(start, stop, x) = a
और y < x
, आप केवल, a
, नहीं stop
अप करने के लिए खोज करने के लिए तब से की जरूरत है;
- यदि
f(start, stop, x)
अपरिभाषित है और y < x
है, तो आपको और अधिक खोजने की आवश्यकता नहीं है।
नोट यदि यह असंभव है कहीं भी start
और stop
के बीच n
या इससे कम लाइनों जगह इस समारोह अपरिभाषित जा सकता है।
ध्यान दें कि आप बार-बार लुकअप को सहेजने के लिए इन कार्यों के लिए अलग से याद कर सकते हैं। आप प्रत्येक पंक्ति के लिए max_lines_at_distance
प्रीकंपूट कर सकते हैं और इसे बाद में कैश में स्टोर कर सकते हैं। फिर, max_distance_for_lines
एक लूप हो सकता है जो कैश को दो सीमाओं के अंदर सामने की जांच करता है।
* निश्चित अंतराल * * पर लाइनों को कैसे रखा जाना चाहिए? जाहिर है, इसका मतलब यह नहीं है कि वे सभी एक-दूसरे के बीच एक ही दूरी हैं (आपका उदाहरण इस पर विरोधाभास करेगा)। क्या लाइनों की क्षैतिज चौड़ाई पर कोई आवश्यकता है? अर्थात। केवल आकार के बीच में बहुत छोटी रेखाएं बनाने से आपको क्या रोक रहा है (जो आपको न्यूनतम संख्या देगा)? –
@NicoSchertler इसका मतलब है कि प्रत्येक लाइन के लिए 'y mod I == 0', जहां y लाइन का वाई समन्वय है। आप सही हैं कि मुझे यहां एक बाधा याद आ रही है, इसलिए मैंने चौथा जोड़ा: आकार के अंदर प्रत्येक उपलब्ध बिंदु 'डी/2' की तुलना में लाइन से आगे नहीं हो सकता है। मैंने मुख्य प्रश्न संपादित किया। लक्ष्य यह है कि यदि एक छेद के साथ एक रेखा टक्कर लगी है, तो हम इसे छेद के बगल में रखना चाहते हैं और इसे बीच में कटौती करने की बजाय इसकी पूरी लंबाई रखना चाहते हैं। इसलिए लाइनों की कुल लंबाई को कम करने के बजाय 'एन' को कम करने का उद्देश्य। – farbro
सामान्य रूप से I> D का कोई गारंटीकृत समाधान नहीं है, क्योंकि तब समानांतर रेखाओं के बीच की जगह डी से अधिक हो सकती है और प्रत्येक पंक्ति से दूर/2 से अधिक उनके मध्य बिंदु - क्या यह भी गारंटी है कि मैं <= डी? – jwimberley