ठीक है, अगर यह सबसे अच्छा कलन विधि उपलब्ध है पता नहीं है, लेकिन मैं एक O (n^2) समाधान के बारे में सोच सकते हैं:
पहले, चक्रीय सरणी की संभावना पर ध्यान न दें। आइए एक सरल समस्या हल करें: सरणी को सॉर्ट करने के लिए न्यूनतम संख्या में स्वैप क्या है।
यहाँ सावधान रहें
, क्योंकि इस एल्गोरिदम छँटाई के बारे में नहीं है। एक comparation आधारित छंटाई एल्गोरिथ्म कम से कम O(n log n)
की बुरी से बुरी हालत के लिए होगा। इस समस्या में, स्वैप की अधिकतम संख्या की जरूरत n
है।
क्यों? क्योंकि यह अधिकतम permutation cycle size है जिसे आप प्राप्त कर सकते हैं। आपको आवश्यक स्वैप की न्यूनतम संख्या बिल्कुल क्रमपरिवर्तन चक्र आकार शून्य है। मेरा मतलब है आप जैसे किसी परिवर्तन चक्र के रूप में सरणी के किसी भी परिवर्तन, .:
3 2 1 4 5
प्रतिनिधित्व कर सकते हैं - आकार 1 के क्रमपरिवर्तन चक्र के लिए>(2)(4)(5)(1 3)
, आप किसी भी स्वैप जरूरत नहीं है। आकार 2 के क्रमपरिवर्तन चक्र के लिए, आपको बिल्कुल 1 स्वैप की आवश्यकता है। >(1 2 3 4 5)
इस सरणी की उपेक्षा कर पहले से ही चक्रीय-छाँटे गए है, इस सरणी tottaly गड़बड़ है -
2 3 4 5 1
: यह रूप में मापता है। इसे सामान्य रूप से सॉर्ट करने के लिए, मुझे 4 स्वैप की आवश्यकता होगी, मूल रूप से 1 को इसकी सामान्य स्थिति में ले जाया जाएगा।
क्रमपरिवर्तन चक्रों की गणना करना बहुत आसान है, यह केवल उस संख्या का पालन करने का विषय है जहां सरणी को सॉर्ट किया गया था। A[0]
पर पिछले उदाहरण
3 2 1 4 5
- शुरू होता है का उपयोग करना;
- क्योंकि
A[0]==3
, और 3 क्रमबद्ध सरणी में तीसरा तत्व होगा, तीसरी स्थिति के बाद;
क्योंकि A[2]==1
, और 1 होगा ..., 1 स्थिति के बाद होगा। जैसा कि हम पहले से ही थे, हमारे पास आकार 2 का चक्र है; अगले विज़िट नहीं किए गए स्थिति (1)
A[1]==2
है यह सही स्थिति है, इसलिए हम कुछ भी करने की जरूरत नहीं है में कम से फिर से
शुरू होता है, यहाँ हम आकार 1 का एक चक्र है।
और बहुत आगे है ...
इस एल्गोरिथ्म हे (एन) है, लेकिन जैसा कि हम सरणी हर संभव स्थिति में शुरू होने वाले (क्योंकि यह परिपत्र है) के लिए ऐसा करने की जरूरत है, हम करेंगे इसे एन बार करें, इसलिए, संपूर्ण एल्गोरिदम ओ (एन^2) है।
अद्यतन; कुछ अजगर कोड मेरी एल्गोरिथ्म को दिखाने के लिए:
def offset_swaps(A, S, offset):
visited = [False]*len(A)
swaps = 0
for i in xrange(len(A)):
if visited[i]: continue
cycle, current = 0, i
while not visited[current]:
cycle += 1
visited[current] = True
current = (S[A[current]] + offset) % len(A)
swaps += cycle - 1
return swaps
def number_of_swaps(A):
S = {x:i for i,x in enumerate(sorted(A))}
min_swaps = len(A)
for i in xrange(len(A)):
min_swaps = min(min_swaps, offset_swaps(A, S, i))
return min_swaps
print number_of_swaps((3, 5, 4, 2, 1))
क्या सरणी में संख्या हमेशा अनुक्रमिक होने जा रही हैं? – DPenner1
क्या आपको केवल स्वैप की संख्या की आवश्यकता है, न कि वास्तविक स्वैप स्वयं? –
"हनोई के टावर्स" को देखो। –