C99 - 3x3 बोर्ड 0.084 में
संपादित करें: मैंने अपना कोड रद्द कर दिया और परिणामों पर कुछ गहन विश्लेषण किया।
आगे के संपादन: समरूपता द्वारा जोड़ा गया प्रुनिंग। यह 4 एल्गोरिथ्म कॉन्फ़िगरेशन बनाता है: अल्फा-बीटा छंटाई के साथ या बिना समरूपता एक्स के साथ
सबसे बड़ा संपादन: एक हैश तालिका का उपयोग करके संस्मरण जोड़ा गया, अंत में असंभव को प्राप्त करना: एक 3x3 बोर्ड को हल करना!
प्राथमिक विशेषताएं:
- अल्फ़ा-बीटा प्रूनिंग के साथ मिनिमैक्स का सीधा कार्यान्वयन
- बहुत कम स्मृति प्रबंधन (मान्य चालों की dll को बनाए रखता है; वृक्ष खोज में प्रति शाखा 1; अपडेट)
- समरूपता द्वारा छंटनी के साथ दूसरी फ़ाइल। फिर भी प्रति शाखा ओ (1) अपडेट प्राप्त करता है (तकनीकी रूप से ओ (एस) जहां एस समरूपता की संख्या है। यह वर्ग बोर्डों के लिए 7 और गैर-वर्ग बोर्डों के लिए 3 है)
- तीसरी और चौथी फाइलें संस्मरण जोड़ती हैं। आपके पास हैशटेबल के आकार (
#define HASHTABLE_BITWIDTH
) पर नियंत्रण है । जब यह आकार दीवारों की संख्या से अधिक या बराबर होता है, तो यह बिना टकराव और O (1) अपडेट की गारंटी देता है। छोटे हैशटेबल्स में अधिक टकराव होगा और थोड़ा धीमा होगा।
-DDEBUG
प्रिंटआउट के लिए संकलन करें
संभावित सुधार:
पहले संपादन में तय की गई छोटी मेमोरी लीक को ठीक करें
अल्फा / बीटा प्रूनिंग 2 एडिट में जोड़े गए
3 राशियों में prune समरूपताएं जोड़ी गईं (ध्यान दें कि समरूपता संस्मरण द्वारा नियंत्रित नहीं की जाती है, ताकि एक अलग अनुकूलन बना रहे।)
4 वें संपादन में संस्मरण जोड़ा गया
- वर्तमान में संस्मरण प्रत्येक दीवार के लिए एक संकेतक बिट का उपयोग करता है। 3x4 बोर्ड में 31 दीवारें होती हैं, इसलिए समय की कमी की परवाह किए बिना यह विधि 4x4 बोर्डों को संभाल नहीं सकती है। सुधार एक्स-बिट पूर्णांक का अनुकरण करना होगा, जहां एक्स कम से कम दीवारों की संख्या के रूप में बड़ी है।
कोड
संगठन की कमी के कारण, फ़ाइलों की संख्या हाथ से बाहर हो गई है। सभी कोड इस Github रिपॉजिटरी में स्थानांतरित कर दिया गया है । संस्मरण संपादन में, मैंने एक मेकफाइल और परीक्षण स्क्रिप्ट जोड़ा।
परिणाम
जटिलता पर नोट्स
ब्रूट-फोर्स डॉट्स के पास पहुंचते हैं और बक्से जटिलता में बहुत जल्दी उड़ जाते हैं ।
R
पंक्तियों और C
स्तंभों के साथ एक बोर्ड पर विचार करें । वहाँ R*C
वर्ग, R*(C+1)
ऊर्ध्वाधर दीवारें और C*(R+1)
क्षैतिज दीवारें हैं। वह कुल है W = 2*R*C + R + C
।
क्योंकि लिम्बिक ने हमें गेम को मिनिमैक्स के साथ हल करने के लिए कहा, हमें खेल के पेड़ की पत्तियों को लांघना होगा। आइए अब के लिए छंटाई को नजरअंदाज करें, क्योंकि जो मायने रखता है वह परिमाण के आदेश हैं।
कर रहे हैं W
पहला कदम के लिए विकल्प। उनमें से प्रत्येक के लिए, अगला खिलाड़ी W-1
शेष दीवारों में से कोई भी खेल सकता है , आदि .. जो हमें एक खोज-स्थान देता है SS = W * (W-1) * (W-2) * ... * 1
, या SS = W!
। तथ्य बहुत बड़े हैं, लेकिन यह केवल शुरुआत है। खोज स्थान में लीफ नोड्सSS
की संख्या है। हमारे विश्लेषण के लिए अधिक प्रासंगिक निर्णय की कुल संख्या है, जिसे बनाया जाना था (यानी पेड़ में शाखाओं की संख्या )। शाखाओं की पहली परत में विकल्प होते हैं। उनमें से प्रत्येक के लिए, अगले स्तर आदि हैं। B
W
W-1
B = W + W*(W-1) + W*(W-1)*(W-2) + ... + W!
B = SUM W!/(W-k)!
k=0..W-1
आइए कुछ छोटे टेबल साइज देखें:
Board Size Walls Leaves (SS) Branches (B)
---------------------------------------------------
1x1 04 24 64
1x2 07 5040 13699
2x2 12 479001600 1302061344
2x3 17 355687428096000 966858672404689
ये संख्या हास्यास्पद हो रही है। कम से कम वे समझाते हैं कि जानवर बल कोड 2x3 बोर्ड पर हमेशा के लिए लटका हुआ क्यों लगता है। 2x3 बोर्ड का खोज-स्थान 2x2 से 742560 गुना बड़ा है । यदि 2x2 को पूरा होने में 20 सेकंड लगते हैं, तो एक रूढ़िवादी एक्सट्रपलेशन 2x3 के लिए निष्पादन के 100 दिनों से अधिक की भविष्यवाणी करता है । स्पष्ट रूप से हमें चुभने की जरूरत है।
प्रूनिंग विश्लेषण
मैंने अल्फा-बीटा एल्गोरिथ्म का उपयोग करके बहुत ही सरल छंटाई जोड़कर शुरुआत की। मूल रूप से, यह खोजना बंद कर देता है कि क्या एक आदर्श प्रतिद्वंद्वी इसे कभी अपने वर्तमान अवसर नहीं देगा। "अरे देखो - मैं बहुत से जीतता हूं अगर मेरा प्रतिद्वंद्वी मुझे हर वर्ग प्राप्त करने देता है!", सोचा कोई एअर इंडिया, कभी।
संपादित करें मैंने सममित बोर्डों के आधार पर छंटाई को भी जोड़ा है। मैं किसी संस्मरण दृष्टिकोण का उपयोग नहीं करता, बस किसी दिन मैं संस्मरण जोड़ देता हूं और उस विश्लेषण को अलग रखना चाहता हूं। इसके बजाय, यह इस तरह काम करता है: अधिकांश लाइनों में ग्रिड पर कहीं और "सममित जोड़ी" होती है। 7 समरूपता (क्षैतिज, ऊर्ध्वाधर, 180 रोटेशन, 90 रोटेशन, 270 रोटेशन, विकर्ण और अन्य विकर्ण) तक हैं। सभी 7 वर्ग बोर्डों पर लागू होते हैं, लेकिन अंतिम 4 गैर-वर्ग बोर्डों पर लागू नहीं होते हैं। इनमें से प्रत्येक समरूपता के लिए प्रत्येक दीवार में "जोड़ी" के लिए एक संकेतक है। यदि, एक मोड़ में जा रहा है, बोर्ड क्षैतिज रूप से सममित है, तो प्रत्येक क्षैतिज जोड़ी में से केवल एक को खेलना होगा।
संपादित करें संस्मरण संपादित करें ! प्रत्येक दीवार को एक अद्वितीय आईडी मिलती है, जिसे मैं आसानी से एक संकेतक बिट के रूप में सेट करता हूं; nth दीवार में आईडी है 1 << n
। एक बोर्ड का हैश, तो, केवल सभी दीवारों की ओआर है। यह O (1) समय में प्रत्येक शाखा में अपडेट किया जाता है। हैशटेबल का आकार एक में सेट किया गया है #define
। सभी परीक्षण आकार 2 ^ 12 के साथ चलाए गए थे, क्योंकि क्यों नहीं? जब हैशटेबल (इस मामले में 12 बिट्स) को अनुक्रमित करने वाली बिट्स की तुलना में अधिक दीवारें होती हैं, तो कम से कम महत्वपूर्ण 12 को मास्क किया जाता है और सूचकांक के रूप में उपयोग किया जाता है। प्रत्येक हैशटेबल इंडेक्स पर एक लिंक की गई सूची के साथ टकराव को नियंत्रित किया जाता है। निम्नलिखित चार्ट मेरे त्वरित-और-गंदे विश्लेषण है कि हैशटेबल आकार प्रदर्शन को कैसे प्रभावित करता है। अनंत रैम वाले कंप्यूटर पर, हम हमेशा टेबल की साइज को दीवारों की संख्या पर सेट करेंगे। एक 3x4 बोर्ड में हैशटेबल 2 ^ 31 लंबा होगा। काश हमारे पास वह विलासिता न हो।
ठीक है, वापस छंटाई करने के लिए .. पेड़ में खोज उच्च रोककर, हम पत्तियों को नीचे नहीं जाकर बहुत समय बचा सकते हैं। 'प्रूनिंग फैक्टर' उन सभी संभावित शाखाओं का अंश है, जिन्हें हमें देखना था। ब्रूट-बल का प्रूनिंग फैक्टर 1. जितना छोटा होता है, उतना ही अच्छा होता है।