यदि आप वास्तव में "जितना संभव हो सके" चाहते हैं तो (1) मुझे यकीन है कि आप भाग्य से बाहर हैं और (2) यदि यह प्राप्त करने योग्य थे तो यह शायद-यादृच्छिक दिखने वाले नतीजों का उत्पादन नहीं करेगा। लेकिन अगर आप चाहते हैं कि "कुछ हद तक दूर" है, तो यह इतना बुरा नहीं है। यहां कुछ चीज़ें दी गई हैं जो आप कर सकते हैं।
(1) अपने एक्स, वाई निर्देशांक की समानता के अनुसार ग्रिड पदों को वर्गीकृत करें: यानी, वे अजीब हैं और यहां तक कि। तस्वीरों को चार मोटे तौर पर बराबर आकार के बैचों में विभाजित करें। अब निर्देशांक की समानता के अनुसार विभिन्न बैचों से चयन करें। निम्नलिखित कोड (जो थोड़ा सा भी "चालाक" है, क्षमा करें) यह करता है, मॉड्यूल बग और टाइपो।
System.Random rng = new System.Random();
for (int x=0; x<nx; ++x) {
for (int y=0; y<ny; ++y) {
k = ((x&1)<<1) + (y&1); // 0..3
int n_photos_in_batch = (n_photos+3-k) >> 2;
int photo_number = (rng.Next(0,n_photos_in_batch-1) << 2) + k;
// use this photo
}
}
डाउनसाइड्स: एक फोटो की प्रतियों को एक-दूसरे से दूर एक कदम से आगे ले जाने के लिए कुछ भी नहीं करता है। कुछ हद तक यादृच्छिकता को कम करता है क्योंकि किसी दिए गए फोटो की सभी प्रतियां पदों के एक निश्चित सबसेट में होंगी; कुछ संदर्भों में यह दिखाई दे सकता है और मूर्खतापूर्ण दिख सकता है।
विविधताएं: हम मूल रूप से 2x2 टाइल्स के साथ ग्रिड को कवर कर रहे हैं, और प्रत्येक टाइल में होने वाली फ़ोटो की सीमा को सीमित कर रहे हैं। आप बड़े टाइल्स, या अलग-अलग आकार के टाइल्स का उपयोग कर सकते हैं, या उन्हें अलग-अलग व्यवस्थित कर सकते हैं। उदाहरण के लिए, यदि आप k = ((x&1)<<1)^(y&3)
कहते हैं तो आपको एक प्रकार-हेक्सागोनल पैटर्न में व्यवस्थित 2x2 टाइल्स मिलते हैं, जो वास्तव में उपरोक्त संस्करण की तुलना में शायद बेहतर है।
(2) अपने ग्रिड में स्थितियों पर लूप (रास्टर ऑर्डर करेगा, हालांकि बेहतर विकल्प हो सकते हैं) और प्रत्येक व्यक्ति एक फोटो चुनता है जो (ए) पहले से ही उस स्थिति के नजदीक नहीं होता है जो आप हैं देख रहे हैं और (बी) अन्यथा यादृच्छिक है। निम्न कोड (फिर से, मॉड्यूलो बग और टाइपो) ऐसा कुछ करता है, हालांकि बड़े ग्रिड के लिए आप इसे और अधिक कुशल बनाना चाहते हैं।
System.Random rng = new System.Random();
radius = MAX_RADIUS; // preferably not too big, so that the search isn't too slow
while ((2*radius+1)*(2*radius+1) >= n_photos) --radius; // gratuitously inefficient!
for (int x=0; x<nx; ++x) {
for (int y=0; y<ny; ++y) {
// which photos already appear too near to here?
System.Collections.BitArray unseen = new System.Collections.BitArray(n_photos,True);
for (x1=x-radius; x1<=x+radius; ++x1) {
for (int y1=y-radius; y1<=y+radius; ++y1) {
if (0 <= x1 && x1 < nx && 0 <= y1 && y1 < nx && (y1<y || (y1==y && x1<x))) {
unseen[photos[x1,y1]] = False;
}
}
}
// now choose a random one of them
int n_unseen = 0;
for (int i=0; i<n_photos; ++i) if (unseen[i]) ++n_unseen;
System.Debug.Assert(n_unseen>0, "no photos available");
int j = rng.Next(0,n_unseen-1);
for (int i=0; i<n_photos; ++i) {
if (unseen[i]) {
if (j==0) { photos[x,y] = i; break; }
--j;
}
}
}
}
नोट: यह बहुत विकल्प 1. x1 पर वैधता की जांच करने से ज्यादा महंगा है, y1 अनावश्यक रूप से अक्षम यहाँ, निश्चित रूप से है। तो त्रिज्या की पसंद है।हालांकि, यदि आप सूची में आने वाले कुछ बदलावों को अपनाते हैं, तो इनके स्पष्ट और अधिक कुशल संस्करण तोड़ सकते हैं। यह कोड, जैसा कि यह खड़ा है, 9 से कम होने पर फ़ोटो को अलग रखने के लिए कुछ भी नहीं करेगा। त्रिज्या की पसंद वास्तव में पूरी तरह से फर्जी है, ग्रिड-ट्रैवर्सल ऑर्डर के लिए मैंने उपयोग किया है, क्योंकि 2r से अधिक नहीं होते^2 + 2 आर "बहिष्कृत" पदों; फिर, यदि आप एक अलग क्रम में ग्रिड को पार करते हैं तो यह बदल सकता है। आदि
विविधताएं: कोई वास्तविक कारण नहीं है कि आप जिस क्षेत्र को खोजते हैं वह वर्ग होना चाहिए। उदाहरण के लिए सर्कुलर बेहतर हो सकता है। आप कुछ अतिरिक्त काम के साथ, उस क्षेत्र का निर्माण कर सकते हैं जिसमें आपके पास फ़ोटो के रूप में हमेशा के रूप में बहुत से अंक हैं (हालांकि यदि आप ऐसा करते हैं तो आपको फ़ोटो का अधिकतर आवधिक पैटर्न मिलेगा, इसलिए थोड़ा कम आक्रामक होना बेहतर होगा)। ग्रिड प्रविष्टियों को एक अलग स्थिति में संसाधित करना बेहतर हो सकता है - उदाहरण के लिए, केंद्र से बाहर बढ़ना।
(3) उपरोक्त विकल्प 2 एक निश्चित सीमा के भीतर तस्वीरों को अनूठा रखेगा (जितना बड़ा होगा उतना ही यह दिया जा सकता है कि आपके पास कितनी अलग तस्वीरें हैं) लेकिन इससे अलग प्रतियों को दूर रखने की परवाह नहीं है। इसके बजाय, आप तय कर सकते हैं कि किसी भी दूरी पर दो समान फ़ोटो कितनी खराब हैं और फिर कुल खराबता को कम करने के लिए फ़ोटो चुनें। यह विकल्प 2 से भी अधिक महंगा होगा। मैं नमूना कोड देने से परेशान नहीं होगा; आप शायद काम कर सकते हैं कि आप इसे कैसे कर सकते हैं।
[जोड़ने के लिए संपादित ...]
(4) यहाँ के विषय पर एक प्यारा परिवर्तन हो (1)। ग्रिड स्क्वायर होने पर यह सबसे अच्छा काम करेगा और इसका आकार 2 की शक्ति है, लेकिन आप इसे आम तौर पर काम करने के लिए अनुकूलित कर सकते हैं। इसमें आपके ग्रिड के आकार के लिए केवल आनुपातिक समय लगता है, हालांकि आपके पास कई तस्वीरें हैं। प्रत्येक स्थिति के लिए (एक्स, वाई): कुछ के लिए निर्देशांक के नीचे के बिट्स के अलावा सभी को फेंक दें। बिट्स को रिवर्स करें और बिट्स को इंटरलीव करें, 0 से 2^(2k) -1 से एक संख्या एम दें। के चुनें, ताकि यह कहीं कहने के क्रम में, n_photos/4 है। अब, स्थिति (एक्स, वाई) पर आप फोटो नंबर राउंड (n_photos * m/2^(2k) + smallish_random_number) डाल देंगे। कुछ विवरण हैं जो मैं आपके लिए भरने के लिए छोड़ दूंगा :-)।
जब मैंने इस प्रश्न को पढ़ा तो मैंने तुरंत सोचा * ["सिम्युलेटेड एनीलिंग,"] (http://en.wikipedia.org/wiki/Simulated_annealing) * क्योंकि यह वही है [एनीलिंग] (http: // en। wikipedia.org/wiki/Annealing_%28metallurgy%29) वास्तविक जीवन में है: परमाणुओं को समय के साथ घटती दर पर झुकाव ताकि वे अपने संतुलन स्थिति में बस सकें। इस समस्या के लिए, यद्यपि, अनुरूपित एनीलिंग की तुलना में शायद एक तेज़/अधिक विश्वसनीय/आसान-से-कोड अनुमान है। –