चींटियों के साथ आकर्षित करें: चींटी कॉलोनी अनुकूलन एल्गोरिदम का उपयोग करके प्रक्रियात्मक छवियां


मैं चींटियों के साथ क्यों आकर्षित करना चाहता था


मैं सॉफ्टवेयर डिजाइन की जटिलता का पता लगाने के लिए कला का काम बनाना चाहता था। जब मैं एक विशाल कोड आधार प्रस्तुत करता हूं, तो मुझे लगता है कि इसके स्वतंत्र रूप से उत्पन्न होने वाली जटिलता और इसके परस्पर जुड़े हुए, परस्पर जुड़े हुए हिस्सों के बारे में। इसका सामान्य रूप, इसलिए बोलना, कई व्यक्तिगत व्यक्तित्वों के कार्यों से उत्पन्न होता है।

मैं इस बारे में सोच रहा था कि इस चित्र को कैसे प्रस्तुत किया जाए, और उन छवियों में से एक जो मुझे एक प्रतिक्रिया मिलीं वह एक चींटी कॉलोनी की छवि थी। चींटियाँ उभरने (उभरने) की जटिलता का एक बड़ा उदाहरण हैं। कोई भी चींटी एक वास्तुकार नहीं है, लेकिन साथ में वे शानदार जटिल संरचनाओं का निर्माण करते हैं।


फॉर्मिकारिया की योजना। स्रोत: विकिमीडिया कॉमन्स

मैंने चींटी कॉलोनियों के सिमुलेशन की जानकारी की तलाश शुरू की। जाहिर है, इस बारे में साहित्य है, और यह सुंदर है । लेकिन चाल यह थी कि एंथिल बालू की भौतिकी और जिस धरती में बने हैं, उसके आधार पर आंशिक रूप से उत्पन्न होते हैं - क्योंकि उनका निर्माण इस बात पर निर्भर करता है कि चींटी के डालने पर कण कैसे स्थित होगा। मैं 2D में कुछ बनाना चाहता था, इसलिए मैंने रेत भौतिकी कोड लिखे बिना सीधे सिमुलेशन में जाने की कोशिश की, यानी मुझे एंथिल के भौतिक सिमुलेशन को छोड़ना पड़ा।

इस वजह से, मैंने फिर से खोजना शुरू किया, और उन्होंने मुझे चींटी सिमुलेशन के पूरी तरह से अलग वर्ग में ले गए:चींटी कॉलोनी अनुकूलन एल्गोरिदम (चींटी कॉलोनी एल्गोरिदम)

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

यह बहुत सरलता से काम करता है। प्रत्येक चींटी अपने मार्ग में "फेरोमोन्स" का एक निशान छोड़ती है। चींटियाँ एंथिल छोड़ने के बाद एक प्रकार का फेरोमोन छोड़ती हैं और दूसरा जब उन्हें भोजन मिलता है। भोजन चाहने वाली चींटियों को एक "भोजन" फेरोमोन का पता लगाने की तलाश होती है, जबकि एंथिल की तलाश करने वाले "होम" फेरोमोन की तलाश करते हैं।

चींटियां जो खुद को एक छोटे रास्ते पर पाती हैं, घर से भोजन तक तेजी से रास्ता तय करती हैं और इसके विपरीत। इसका मतलब है कि वे फेरोमोन की एक अधिक संतृप्त परत बनाएंगे। अधिक समय तक चलने वाली चींटियां एक अमीर ट्रैक को पसंद करेंगी और एक छोटे रास्ते के साथ आगे बढ़ेंगी। प्रत्येक व्यक्ति चींटी बहुत सरल नियमों के अनुसार काम करती है, लेकिन समय के साथ चींटियों को दो बिंदुओं के बीच एक अधिक इष्टतम मार्ग मिल जाता है।

सिमुलेशन


मैंने अपने चींटी सिम्युलेटर को प्रसंस्करण 3 पर लिखा। मैंने ग्रेगरी ब्राउन द्वारा इस अद्भुत पोस्ट से कोड का अनुकरण करके अपना कार्यान्वयन शुरू किया

चींटियों को स्थानांतरित करने के बाद, मैंने कोड का विस्तार और संशोधन करना शुरू कर दिया ताकि यह बड़े पिक्सेल ग्रिड में बेहतर काम करे। मैं दिलचस्प दिखने वाले सिमुलेशन (आवश्यक रूप से प्रभावी नहीं ) प्राप्त करना चाहता था और जिसने कोड पर अपना काम निर्धारित किया। मैंने चींटियों के लिए एक बहुत अल्पविकसित दृष्टि बनाई ताकि प्रत्येक चींटी आगे कई पिक्सेल देख सके। मैंने चींटियों की मृत्यु और पुनर्जन्म को जोड़ा ताकि वे पूरे अंतरिक्ष में बेतरतीब ढंग से फैल न सकें। अंत में, मैंने चींटियों को थोड़ा सुस्त बना दिया: वे फेरोमोन को लगातार छोड़ते हैं, भले ही वह खोज असफल रही हो, जो चींटियों के वास्तविक व्यवहार के समान है।

यहाँ आप अपने ब्राउज़र में p5.js पर सिमुलेशन पोर्ट खेल सकते हैं!

आप Github पर पोर्ट किए गए स्रोत कोड पर भी नज़र डाल सकते हैं

सिमुलेशन में सबसे अधिक, मुझे चींटियों द्वारा बनाई गई सुंदर, अजीब और जटिल आकृतियों से मोहित किया गया था। वे सीधी रेखाओं में मार्च नहीं करते हैं, लेकिन लूप, घुमाव और शाखाएं बनाते हैं। इससे भी अधिक दिलचस्प यह है कि आप चींटियों द्वारा बनाए गए आंकड़ों की उपस्थिति को उनकी दुनिया के विभिन्न चर को बदलकर नियंत्रित कर सकते हैं। उदाहरण के लिए, आप फेरोमोन वाष्पीकरण दर और पिक्सेल में चींटियों की दृष्टि की सीमा को बदल सकते हैं।

चींटियों को कला में बदल दें


सिमुलेशन काम करना शुरू करने के बाद, अगला कदम यह आउटपुट डेटा का अध्ययन करना था। मेरा लक्ष्य कुछ प्रकार की द्वि-आयामी छवि बनाना था, अर्थात, मुझे चींटियों द्वारा बनाई गई आकृतियों को पकड़ने और आकर्षित करने की आवश्यकता थी।

अंत में, मैंने विभिन्न प्रकार के आउटपुट लिखे: कई प्रकार के रेखापुंज आउटपुट और एक वेक्टर। रेखापुंज उत्पादन को पकड़ने के लिए, मैंने चींटियों द्वारा देखी गई कोशिकाओं और उनकी यात्राओं की आवृत्ति को ट्रैक किया। इस निष्कर्ष के फिल्टर के साथ खेलने के बाद, आप उन जगहों का भूतिया पता लगा सकते हैं जहां चींटियों ने दौरा किया था।


रेखापुंज उत्पादन का एक उदाहरण। रास्ते लोकप्रिय चींटी पटरियों के साथ बहुत व्यापक हैं और जहां चींटियाँ चींटी पहाड़ी के चारों ओर बेतरतीब ढंग से घूमती हैं।

रेखापुंज उत्पादन दिलचस्प था, लेकिन मैं व्यक्तिगत पथों को अधिक स्पष्ट रूप से देखना चाहता था, इसलिए मैंने svg को निर्यात करने की संभावना का पता लगाया। वेक्टर आउटपुट के लिए, मैंने प्रत्येक चींटी के इतिहास को बचाया, और जब वे भोजन या एंथिल तक पहुंचे, तो मैंने इस कहानी को सूची में लिख दिया। प्रतिपादन के लिए, मैंने प्रत्येक सहेजे गए पथ का नमूना लिया और इसे घटता की श्रृंखला के रूप में प्रस्तुत किया।


वेक्टर आउटपुट का एक उदाहरण। यहां आप चींटियों के अलग-अलग रास्ते देख सकते हैं। जहाँ कई चींटियाँ हो गई हैं, वहाँ थोड़ी सी अतिव्यापी रेखाएँ व्यापक पथ बनाती हैं।

बिंदुओ को जोडो


मुझे पता था कि मैं कई बिंदुओं के बीच यात्रा करने वाली चींटियों को आकर्षित करना चाहता था, इसलिए कई सिमुलेशन को एक छवि में जोड़ने के लिए कोड पहले में से एक था। लेकिन फिर मुझे क्या आकर्षित करना चाहिए?

पहले तो मैंने बहुत शाब्दिक ग्राफ बनाने का फैसला किया: सरल बाइनरी पेड़ों से शुरू, फिर अधिक जटिल विज़ुअलाइज़ेशन पर आगे बढ़ें। यह एक प्राकृतिक कदम की तरह लग रहा था, क्योंकि चींटी कॉलोनी का अनुकूलन रेखांकन में पथ खोजने की समस्या को हल करता है। मैंने यह भी सोचा कि यह कोड की जटिलता की कल्पना करने का एक दिलचस्प तरीका होगा: क्यों नहीं यूएमएल आरेख या निर्भरता ग्राफ लिया जाए और उन्हें चींटियों के साथ प्रस्तुत किया जाए?

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

द्विआधारी पेड़ों के साथ प्रयोग आशाजनक लग रहा था और एक बहुत ही प्राकृतिक, जैविक रूप दिया।


एक साधारण बाइनरी ट्री। मुझे बताया गया कि यह एंजियोग्राम की तरह है।


थोड़ा और जटिल पेड़, पहले से ही काफी गहरा।

फिर मैंने इनपुट के रूप में विभिन्न कोड आधारों का उपयोग करके अधिक ग्राफ़ बनाना शुरू किया। मैंने कुछ सरल पायथन स्क्रिप्ट लिखीं: एक ने गिट वृक्ष को डॉट फ़ाइल में बदल दिया, दूसरे ने सी आयात निर्भरता को डॉट फ़ाइल में बदल दिया।


चींटियों द्वारा खींची गई गिट ऑब्जेक्ट ट्री में वस्तुओं का ग्राफ।


लिनक्स कर्नेल में फ़ाइलों के बीच निर्भरता। रेखांकन और रेखांकन ग्राफ के वर्ग शैली का उपयोग करके बनाए गए थे। वास्तव में, यादृच्छिक रेखांकन की तुलना में बहुत अधिक दिलचस्प नहीं है।

हालांकि ये सभी ग्राफ़ दिलचस्प और निश्चित रूप से जटिल हैं, मुझे निराशा हुई कि वास्तव में उन्होंने कोड बेस के सामान्य रूप के बारे में कुछ नहीं कहा, जिस पर उनका निर्माण किया गया था। जितना मैंने कोड विज़ुअलाइज़ेशन के साथ प्रयोग किया, उतना ही मुझे एहसास हुआ कि एक कोड बेस से एक दिलचस्प ग्राफ का निर्माण अपने आप में एक अलग, अधिक कठिन काम है। हालांकि, मुझे बहुत बड़े ग्राफ़ की जटिलता पसंद आई और बाद में मैं फिर से इस पर लौट आया।

मेरा अगला प्रयोग सरल रूपों के साथ खेल था। मैंने रेखाओं, मंडलियों, साइनसोइड्स और अन्य आकृतियों से रेखांकन बनाया जो नोड्स और किनारों के साथ वर्णन करना आसान है।


खंड पर बिंदु, खंड के दाईं ओर, अंक एक दूसरे के करीब हैं।


विभिन्न साइन लहर आवृत्तियों। मुझे लगता है कि चींटियों से काफी अच्छा आस्टसीलस्कप निकलेगा।

सबसे सरल त्रिभुज स्थान मुझे सबसे दिलचस्प लगा। मैंने कई समान रूप से वितरित अंक उत्पन्न किए - या तो बेतरतीब ढंग से या आकृतियाँ बनाकर - और फिर इन बिंदुओं को एक डिलायना ट्राइंगुलेशन या वोरोनोई आरेख में बदलने के लिए प्रोसेसिंग लाइब्रेरी का उपयोग किया। फिर, परिणामस्वरूप पसलियों को चींटियों को अनुकरण करने के लिए इस्तेमाल किया गया था, जहां प्रत्येक पसली ने एक "चींटी पहाड़ी" या "भोजन" को दर्शाया था।


चींटियों वोरोनोई आरेख द्वारा खींचा गया।

इसके कारण जटिल चींटी पेचीदगियों के एक सुंदर पूर्ण स्थान की उपस्थिति हुई, जिसने उस जटिलता का वर्णन किया जो मुझे बहुत बेहतर लगी।

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


चींटियों के रास्ते एक सरल भूलभुलैया को हल करने की कोशिश कर रहे हैं। आप चींटियों के आकार को देख सकते हैं, जहाँ पर चींटियाँ नहीं जा सकतीं।

मुझे यह विचार था कि यदि चींटियां सरल माज़ों को हल कर सकती हैं, तो आप उन्हें एक साथ जोड़कर एक बड़ा काम बना सकते हैं। मैंने सिमुलेशन चर स्थापित करने में बहुत समय बिताया, ताकि चींटियां उन्हें हल कर सकें, लेकिन मैं अभी भी उन्हें मज़ाक से हल करने के लिए नहीं मिला। अंत में, यह सब चींटी रास्तों के कर्ल में बदल गया, केवल भूलभुलैया के आकार द्वारा सीमित।

कला का काम खत्म


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


पूरा हुआ सिमुलेशन रन। इसमें कई सुपरिम्पोज्ड पथ शामिल हैं जिनसे फजी स्पॉट प्राप्त होते हैं।

अंतिम मुद्दा यह था कि एसवीजी को कैसे खत्म किया जाए। प्रयोगों से, मुझे पता था कि मैं सुंदर आकार के साथ रास्तों को उजागर करने के लिए किसी तरह से मार्गों को क्रमबद्ध करना चाहता था। लेकिन समाप्त सिमुलेशन के रन में एक से दो घंटे लगे, यही वजह है कि प्रयोग के प्रत्येक रन में चर को बदलना असुविधाजनक था।

मैंने एक दूसरा प्रसंस्करण आरेख लिखने का फैसला किया जो सिमुलेशन आउटपुट को एसवीजी में लोड करेगा और फिर मुझे आवश्यक दृश्य प्रभाव लागू करेगा। इसके अलावा, मैं पोस्ट-प्रोसेसिंग स्क्रिप्ट को इंटरएक्टिव बनाना चाहता था ताकि मैं अलग-अलग वज़न और लाइनों के रंगों के साथ प्रयोग कर सकूं, साथ ही साथ थ्रेसहोल्ड भी।

मैंने उन पथों का मूल्यांकन करने के लिए कई अलग-अलग तरीकों की कोशिश की, जो अग्रभूमि में और पृष्ठभूमि में होने चाहिए। कई अलग-अलग कारकों की गणना की गई: लाइन के आत्म-चौराहों की संख्या, इसकी ढलान लाइन की रेखा से चौराहों की संख्या, और संभावना है कि रेखा पिछले दो बिंदुओं द्वारा अनुमानित ढलान का पालन करेगी।

मैंने इन अनुमानों के विभिन्न भारों और मूल्यों के साथ प्रयोग के लिए पोस्ट-प्रोसेसिंग स्क्रिप्ट का उपयोग किया, जब तक मुझे वह लुक नहीं मिला, जिसकी मुझे आवश्यकता थी।


सामने और पृष्ठभूमि लाइनों के लिए थ्रेसहोल्ड सेटिंग।

इस बिंदु पर, प्रत्येक चर को बदलते समय छवि को बचाने से बहुत मदद मिली। जब मुझे अपनी ज़रूरत की छवि के बारे में पता चला, तो एक समय में कई कारकों को बदलने की तुलना में कई मामूली बदलावों की तुलना करना बहुत आसान था।

एक लंबे सेटअप और छोटे बदलाव करने के बाद, मैंने अपने सिमुलेशन से निम्न छवि बनाई:


मैं उस क्षेत्र पर ज़ूम किया जो मुझे सबसे दिलचस्प लगा, और खाली और भरी हुई जगह के बीच एक अच्छा संतुलन बनाने के लिए इसे क्रॉप किया।

अंतिम चरण इस बात का विकल्प था कि इस छवि को भौतिक वस्तु में कैसे बदलना है। मैं उन्हें 40 × 50 सेमी के पोस्टर के रूप में डिजिटल रूप से प्रिंट करने और रंगीन पेपर पर स्क्रीन को प्रिंट करने का असफल (असफल) प्रयास करता था। डिजिटल रूप से मुद्रित पोस्टर बहुत अच्छा लगता है, लेकिन भविष्य में मैं चित्र के भाग के रूप में छवि को कॉपी करना चाहता हूं। मुझे जटिल चित्र ध्यानपूर्ण लगते हैं और मुझे लगता है कि मैं उन्हें मैन्युअल रूप से खींचकर दिलचस्प प्रभाव प्राप्त कर सकता हूं।

इस परियोजना पर मेरी अपेक्षा से अधिक समय व्यतीत किया गया था, और यह शुरुआत के मुकाबले अधिक जटिल निकला। लेकिन यह सभी प्रकार की कम्प्यूटेशनल ज्यामिति और एल्गोरिथम समस्याओं के साथ प्रयोग करने का एक शानदार तरीका है। मुझे लगता है कि यह बहुत विडंबना है कि मैंने जटिलता पर काम करने के लिए कोड की कई हजार पंक्तियां लिखीं, लेकिन मुझे खुशी है कि यह अच्छी लगती है और अपने आप से बोलती है।

Source: https://habr.com/ru/post/undefined/


All Articles