मेरे पास एक स्टोर है जिसमें आइटम हैं। प्रत्येक आइटम या तो एक घटक (जो परमाणु है) या एक उत्पाद जिसमें विभिन्न घटकों (लेकिन एक ही घटक के 2 या अधिक नहीं) होते हैं।उत्पाद असेंबली/डिस्सेप्टर्स को अनुकूलित करना
- दुकान उत्पाद की आवश्यक संख्या में शामिल हैं:
अब, जब मैं दुकान के बाहर एक उत्पाद प्राप्त करना चाहते हैं, वहाँ विभिन्न परिदृश्यों हैं।
- स्टोर में ऐसे घटक होते हैं जिनमें से मैं उत्पाद को इकट्ठा कर सकता हूं।
- स्टोर में ऐसे उत्पाद हैं जो आवश्यक उत्पाद के साथ घटक साझा करते हैं। मैं उनको अलग कर सकता हूं और आवश्यक वस्तु को इकट्ठा कर सकता हूं।
- उपर्युक्त का कोई भी संयोजन।
नीचे आप मेरा कोड अब तक देख सकते हैं (getAssemblyPath
)। यदि आवश्यक हो तो आवश्यक वस्तु को इकट्ठा करने का एक तरीका मिलता है, लेकिन यह असेंबली पथ को अनुकूलित नहीं करता है।
मैं दो तरह से पथ अनुकूलित करना चाहते हैं:
- पहले, पथ जो विधानसभा/disassembly कार्रवाई की कम से कम संख्या लेता चुनें।
- दूसरा, यदि ऐसे कई पथ हैं, तो उस पथ का चयन करें जो स्टोर में कम से कम अलग-अलग घटकों को छोड़ देता है।
अब, मैं इस अनुकूलन को कैसे प्राप्त कर सकता हूं इस बारे में पूरी तरह से नुकसान हुआ हूं (मुझे यह भी यकीन नहीं है कि यह एसओ या गणित के लिए एक प्रश्न है)।
मैं getAssemblyPath
कैसे बदल सकता हूं ताकि यह मेरी अनुकूलन आवश्यकताओं को पूरा कर सके?
मेरे कोड अब तक:
#! /usr/bin/python
class Component:
def __init__ (self, name): self.__name = name
def __repr__ (self): return 'Component {}'.format (self.__name)
class Product:
def __init__ (self, name, components):
self.__name = name
self.__components = components
@property
def components (self): return self.__components
def __repr__ (self): return 'Product {}'.format (self.__name)
class Store:
def __init__ (self): self.__items = {}
def __iadd__ (self, item):
item, count = item
if not item in self.__items: self.__items [item] = 0
self.__items [item] += count
return self
@property
def items (self): return (item for item in self.__items.items())
@property
def products (self): return ((item, count) for item, count in self.__items.items() if isinstance (item, Product))
@property
def components (self): return ((item, count) for item, count in self.__items.items() if isinstance (item, Component))
def getAssemblyPath (self, product, count):
if product in self.__items:
take = min (count, self.__items [product])
print ('Take {} of {}'.format (take, product))
count -= take
if not count: return
components = dict ((comp, count) for comp in product.components)
for comp, count in self.components:
if comp not in components: continue
take = min (count, components [comp])
print ('Take {} of {}'.format (take, comp))
components [comp] -= take
if not components [comp]: del components [comp]
if not components: return
for prod, count in self.products:
if prod == product: continue
shared = set (prod.components) & set (components.keys())
dis = min (max (components [comp] for comp in shared), count)
print ('Disassemble {} of {}.'.format (dis, prod))
for comp in shared:
print ('Take {} of {}.'.format (dis, comp))
components [comp] -= take
if not components [comp]: del components [comp]
if not components: return
print ('Missing components:')
for comp, count in components.items():
print ('{} of {}.'.format (count, comp))
c1 = Component ('alpha')
c2 = Component ('bravo')
c3 = Component ('charlie')
c4 = Component ('delta')
p1 = Product ('A', [c1, c2])
p2 = Product ('B', [c1, c2, c3])
p3 = Product ('C', [c1, c3, c4])
store = Store()
store += (c2, 100)
store += (c4, 100)
store += (p1, 100)
store += (p2, 100)
store += (p3, 10)
store.getAssemblyPath (p3, 20)
यह आउटपुट:
Take 10 of Product C
Take 10 of Component delta
Disassemble 10 of Product A.
Take 10 of Component alpha.
Disassemble 10 of Product B.
Take 10 of Component charlie.
कौन सा काम करता है, लेकिन यह अनावश्यक रूप से जुदा उत्पाद एक करता है, उत्पाद बी आवश्यक घटक अल्फा और चार्ली के दोनों शामिल है के रूप में ।
-
संपादित करें:
Blckknght की बहुत समझदार प्रश्नों का उत्तर देना:
जब आप कहते हैं कि आप चाहते हैं "विधानसभा/disassembly कार्रवाई की कम से कम संख्या", आप क्या मतलब है वस्तुओं की सबसे छोटी संख्या, या विभिन्न उत्पादों की सबसे छोटी संख्या?
एक "asm/disasm action" एक उत्पाद को इकट्ठा करने या अलग करने की क्रिया है, भले ही कितने घटक शामिल हों। मैं कम से कम छूटे हुए सामानों की तलाश में हूं, इससे कोई फर्क नहीं पड़ता कि वे अलग हैं या नहीं।
क्या उत्पाद ए के 10 को अलग करने और उत्पाद बी के अतिरिक्त 5 को अलग करने के लिए उत्पाद ए के 20 को अलग करना बेहतर है?
उत्तरार्द्ध इष्टतम के करीब है।
आगे, आप कहते हैं कि आप पीछे कई घटकों को छोड़ने से बचना चाहते हैं, लेकिन आपके वर्तमान कोड में सभी अलग-अलग घटक जो अनुरोधित उत्पाद द्वारा उपयोग नहीं किए जाते हैं, खो जाते हैं। क्या वह जानबूझकर है (यानी, क्या आप अन्य घटकों को फेंकना चाहते हैं), या यह एक बग है?
विधि getAssemblyPath
केवल आइटम को प्राप्त करने का तरीका निर्धारित करता है। यह वास्तविक स्टोर को छूता नहीं है। किसी भी पल में यह self.__items
को असाइन करता है। इसे एक ऐसे कार्य के रूप में सोचें जो दुकान के आदेश को जारी करता है, उसे अपने स्टोर से आवश्यक वस्तु की आवश्यक मात्रा प्राप्त करने के लिए, (मध्यवर्ती) भविष्य में उसे क्या करना चाहिए।
-
संपादित करें 2:
इस मुद्दे से निपटने के लिए सबसे पहले स्पष्ट (या कम से कम मेरे लिए स्पष्ट) भी तरह से, के साथ घटकों की अधिकतम राशि पहले उन उत्पादों खोज करने के लिए, कि शेयर है आवश्यक उत्पाद, क्योंकि आप प्रत्येक पृथक्करण से अधिक आवश्यक घटक प्राप्त करते हैं। लेकिन दुर्भाग्यवश यह आवश्यक नहीं है इष्टतम पथ उपज। उदाहरण के लिए लें:
उत्पाद ए घटक α, β, γ, δ, ε और ζ शामिल हैं।
उत्पाद बी घटक α, β, η, δ, ε और θ शामिल हैं।
उत्पाद सी घटक α, β, γ, ι, κ और λ शामिल हैं।
उत्पाद डी घटक μ, ν, ξ, δ, ε और ζ शामिल हैं।
हम ए, बी के 100, सी के 100 और डी के 100 की दुकान 0 में है हम अब ए के 10 की आवश्यकता होती है, तो हम उत्पादों एक साथ सबसे अधिक घटकों प्रयोग करती है, के लिए पहले देखो, हम बी मिलेगा हम 10 में से प्रत्येक को α, β, δ और ε प्राप्त करने के 10 को अलग करते हैं। लेकिन फिर हमें 10 सी (γ पाने के लिए) और डी के 10 (ζ प्राप्त करने के लिए) को अलग करने की आवश्यकता है। ये 40 कार्य होंगे (30 अलग-अलग और 10 संयोजन)। लेकिन इष्टतम तरीका डी के 10 और डी के 10 (30 क्रियाएं, 20 अलग-अलग और 10 संयोजन) को अलग करना होगा।
-
संपादित करें 3:
आप इनाम जीतने के लिए अजगर कोड पोस्ट करने के लिए जरूरत नहीं है। बस मुझे एल्गोरिदम समझाएं और दिखाएं कि यह वास्तव में इष्टतम पथ उत्पन्न करता है, या कई मौजूद होने पर ऑप्टिमा में से एक है।
जब आप कहते हैं कि आप "कम से कम असेंबली/डिस्सेप्लर क्रियाएं" चाहते हैं, तो क्या आपके पास सबसे छोटी संख्या में आइटम या विभिन्न उत्पादों की सबसे छोटी संख्या है? यही कारण है, है बेहतर dissassemble को उत्पाद ए की 20 से उत्पाद ए की 10 और उत्पाद बी की एक अतिरिक्त 5 dissassemble के लिए है? इसके अलावा, आप कहते हैं कि तुम पीछे कई घटक छोड़ने से बचना चाहते हैं, लेकिन अपने वर्तमान कोड में सभी disassembled घटक है कि अनुरोध किया उत्पाद का उपयोग नहीं करतीं खो जाते हैं। क्या वह जानबूझकर है (यानी, क्या आप अन्य घटकों को फेंकना चाहते हैं), या यह एक बग है? – Blckknght
आप टिप्पणी के लिए बहुत बहुत धन्यवाद, Blckknght। कृपया मेरा अद्यतन प्रश्न देखें। – Hyperboreus