2016-03-03 4 views
5

में प्रतिबंधों के साथ एक सूची को shuffling मुझे Python (3) में प्रतिबंधों के साथ एक सूची यादृच्छिक करने में एक समस्या है। मैंने इससे संबंधित कुछ अन्य प्रश्न देखे हैं, लेकिन उनमें से कोई भी वास्तव में मेरी समस्या का समाधान नहीं कर रहा है। मैं एक नौसिखिया हूँ, इसलिए किसी भी मदद की बहुत सराहना की है!पायथन

मैं दो प्रकार के उत्तेजना का उपयोग करके एक प्रयोग तैयार कर रहा हूं: आकार और रंग (प्रत्येक में से चार)। मैं सभी 16 संयोजनों, जो मैं random.shuffle-समारोह के साथ किया है के क्रमपरिवर्तन उत्पन्न करने के लिए की जरूरत है:

import random 

# letters are shapes, numbers are colors 
x=["a1","a2","a3","a4","b1","b2","b3","b4","c1","c2","c3","c4","d1","d2","d3","d4"] 

random.shuffle(x) 

अब तक तो अच्छा। हालांकि, मैं अपने परिणाम में उत्तराधिकार में दो बार प्रकट होने के लिए एक आकार (अक्षर) या रंग (संख्या) से बचना चाहता हूं (उदाहरण के लिए "ए 2" "ए 4" या "सी 2" के बाद "ए 2")।

क्या ऐसा कोई प्रतिबंध बनाने का कोई तरीका है?
अग्रिम धन्यवाद!

+3

अब तक तो अच्छा में एक उचित जवाब देना चाहिए? 'random.shuffle (x) 'कोई नहीं देता है क्योंकि यह जगह में' x' shuffles। इसलिए, 'परिणाम' कोई नहीं होगा। – zondo

+0

यह एक ग्राफ समस्या की तरह लगता है। प्रत्येक नोड में एक ही आकार या रंग (इसलिए (एन -1)^2 किनारों प्रति नोड के अलावा अन्य सभी नोड्स को इंगित करने वाला किनारा होता है)। और फिर आप एक यादृच्छिक ट्रैवर्सल चाहते हैं जो हर चरम पर एक बार हिट करता है - एक हैमिल्टनियन पथ जो मुझे लगता है। –

+0

@ ज़ोंडो ओह ठीक है, इसे इंगित करने के लिए धन्यवाद। मैंने उदाहरण को सही किया है। – Frederik

उत्तर

1

कुछ इस तरह एक उचित समय

import random 
while 1: 
    choices = ["a1", "a2","a3","b1","b2","b3","c1","c2","c3"] 

    shuffle = [] 

    last = "" 

    while choices: 
     l = choices 
     if last: 
      l = [x for x in l if x[0] != last[0] and x[1] != last[1]] 
     if not l: 
      #no valid solution 
      break 
     newEl = random.choice(l) 
     last = newEl 
     shuffle.append(newEl) 
     choices.remove(newEl) 
    if not choices: 
     print(shuffle) 
     break 
+0

डाउनवोट के लिए धन्यवाद ;-) यदि आपके पास एक बेहतर समाधान है तो आप आपको बताने के लिए स्वतंत्र हैं –

+1

मैं भी डाउनवोट के बारे में उत्सुक हूं। मैंने आपके समाधान की कोशिश की और ऐसा लगता है कि यह काम करता है। –

+0

मैं इसे सौंपने से पहले कोड का परीक्षण करता हूं ;-) –

4

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

ध्यान दें कि ज़िप का उपयोग करके, आपको वास्तव में जोड़े के सेट मिलेंगे जो आपको परिणाम से प्रत्येक जोड़ी प्राप्त करके अपना परीक्षण संभालने में सक्षम बनाएंगे।

इस विशेष मामले में प्रत्येक रंग सूची आकार का एक सदस्य है, जबकि प्रत्येक रंग सूची रंग

shapes = ['a', 'b', 'c', 'd'] 
colors = ['1', '2', '3', '4'] 
zip(shapes, colors) 
[('a', '1'), ('b', '2'), ('c', '3'), ('d', '4')] 

यह हमें प्रत्येक व्यक्ति फेरबदल एक ही बार में और उसके बाद सभी 16 संभावनाएं पैदा करने के बजाय देता है का एक सदस्य है उन्हें शफल करना यह आपको अपने परीक्षण को बेहतर बनाने में सक्षम हो सकता है।

यदि आप यह सुनिश्चित करना चाहते हैं कि सूचियों के दो सेटों के समान समूह में समान रंग या आकार नहीं है, तो पिछले सेटिंग के विरुद्ध शफल होने के बाद आप इसके लिए परीक्षण कर सकते हैं।

testing = True 
while testing: 
    newcolors = colors 
    random.shuffle(newcolors) 
    # perform the test that you want to make get testresult True or False 
    if testresult: 
     colors = newcolors 
     testing = False 

इस उथल रखेंगे जब तक testresult सच हो जाता है और random.shuffle से सभी अमान्य परिणाम त्यागें()

-1

आप तकनीकी रूप से itertools.permutations इस्तेमाल कर सकते हैं जबकि (मुझे लगता है कि पहले की कोशिश की), कि लंबे समय तक भी ले जाएगा।

from random import shuffle 

x=["a1","a2","a3","a4","b1","b2","b3","b4","c1","c2","c3","c4","d1","d2","d3","d4"] 

def pairwise(some_list): 
    one = iter(some_list) 
    two = iter(some_list) 
    next(two) 
    for first, second in zip(one, two): 
     yield first, second 

while True: 
    shuffle(x) 
    for first, second in pairwise(x): 
     if first[0] == second[0] or first[1] == second[1]: 
      break 
    else: # nobreak: 
     print(x) 
-1

आप सूची टुकड़ा अंतिम मान के लिए एक यादृच्छिक विकल्प की तुलना द्वारा बुद्धिमान निर्माण कर सकते हैं:

उपयोग इस आइटम है कि एक संपत्ति eachother के निम्नलिखित हिस्सा बिना यादृच्छिक दृश्यों उत्पन्न करने के लिए।

import random 

options = ["a1", "a2", "a3", "a4", "b1", "b2", "b3", "b4", 
      "c1", "c2", "c3", "c4", "d1", "d2", "d3", "d4"] 

j = random.choice(range(len(options))) 
result = [options.pop(j)] 
last = result[-1] 
while options: 
    j = random.choice(range(len(options))) 
    candidate = options[j] 
    if all([x != y for x, y in zip(last, candidate)]): 
     result.append(options.pop(j)) 
     last = result[-1] 
1

मुझे शक है इस सबसे अच्छा तरीका है, लेकिन यह ऐसा करने का एक तरीका है। आप इस

a1, b1, c1, d1 
a2, b2, c2, d2 
a3, b3, c3, d3 
a4, b4, c4, d4 

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

import random 
shapes_and_colors=["a1","a2","a3","a4","b1","b2","b3","b4","c1","c2","c3","c4","d1","d2","d3","d4"] 
nRows = 4 
nCols = 4 
inds = [(x,y) for x in range(nRows) for y in range(nCols)] 
def make_random(someArr): 
    toRet = [] 
    n = len(someArr) 
    for i in range(n): 
     possible = [thing for thing in someArr if thing not in toRet] 
     prev = poss = None 
     while poss is None: 
      next_val = random.choice(possible) 
      if next_val == prev: 
       #failed so try again 
       return make_random(someArr) 
      if not toRet or (next_val[0] != toRet[-1][0] and next_val[1] != toRet[-1][1]): 
       poss = next_val 
      prev = next_val 
     toRet += poss, 
    return toRet 



ans= [thing for thing in make_random(shapes_and_colors)] 
print ans 

आउटपुट के बाद एक युगल चलाता

['c3', 'd4', 'c1', 'd3', 'b1', 'a4', 'b3', 'c4', 'a3', 'b2', 'a1', 'c2', 'd1', 'a2', 'b4', 'd2'] 
['d4', 'b3', 'c1', 'a4', 'b2', 'c4', 'd3', 'a1', 'c3', 'a2', 'b4', 'd2', 'a3', 'b1', 'c2', 'd1'] 

अस्वीकरण

चूंकि यह एक पूरी तरह से अनुभवहीन दृष्टिकोण है, यह कभी कभी अटक जाती है बन जाता है! तो मान लें कि शेष दो सूचकांक शेष हैं [(2, 2), (3, 2)]। फिर, प्रतिबंधों को तोड़ने के बिना एल्गोरिदम आगे बढ़ने का कोई संभावित तरीका नहीं है। अभी, मैं इसे एक रिकर्सिव कॉल के साथ संभालने वाला हूं, जो आदर्श नहीं है।