ठीक है, यह समस्या वास्तव में रैखिक अनुक्रमों के चारों ओर घूमती है।
f(n) = 1 + 2 + ... + n - 1 + n
इस तरह के एक दृश्य की राशि के बराबर है:: 1 की एक न्यूनतम मूल्य के साथ अनुक्रम पर विचार
f(n) = n * (n + 1)/2
तो एन = 4 के लिए, एक उदाहरण के रूप, योग 10 है इसका मतलब है कि यदि आप 4 अलग-अलग संख्याओं का चयन कर रहे हैं तो न्यूनतम शून्य कुल शून्य नहीं है और कोई नकारात्मक नहीं है 10. अब रिवर्स में जाएं: यदि आपके पास कुल 10 और 4 संख्याएं हैं तो केवल संयोजन (1,2, 3,4)।
तो सबसे पहले आपको यह जांचने की आवश्यकता है कि आपका कुल कम से कम इस निचले बाउंड के रूप में उच्च है या नहीं। यदि यह कम है तो कोई संयोजन नहीं है। यदि यह बराबर है, तो एक संयोजन ठीक है। यदि यह अधिक है तो यह अधिक जटिल हो जाता है।
अब कल्पना करें कि आपकी बाधाएं कुल संख्या 12 के साथ हैं। हमने पाया है कि f (4) = 10. लेकिन क्या होगा यदि पहला (निम्नतम) संख्या 2 है?
2 + 3 + 4 + 5 = 14
तो पहला नंबर 1 से अधिक नहीं हो सकता है। आप अपना पहला नंबर जानते हैं। अब आप कुल संख्या 11 के साथ 3 संख्याओं का अनुक्रम उत्पन्न करते हैं (12 - 1 होने के नाते)।
1 + 2 + 3 = 6
2 + 3 + 4 = 9
3 + 4 + 5 = 12
दूसरा नंबर 2 होना चाहिए क्योंकि यह एक नहीं हो सकता है। यह 3 नहीं हो सकता है क्योंकि 3 से शुरू होने वाली तीन संख्याओं की न्यूनतम संख्या 12 है और हमें 11.
अब हमें दो संख्याएं मिलती हैं जो 9 (12 - 1 - 2) तक 3 होती हैं सबसे कम संभव है।
3 + 4 = 7
4 + 5 = 9
तीसरा नंबर 3 या 4 हो सकता है। तीसरे नंबर के साथ अंतिम तय किया गया है। दो संभावित संयोजन हैं:
1, 2, 3, 6
1, 2, 4, 5
आप इसे एक सामान्य एल्गोरिदम में बदल सकते हैं।इस पुनरावर्ती कार्यान्वयन पर विचार करें:
$all = all_sequences(14, 4);
echo "\nAll sequences:\n\n";
foreach ($all as $arr) {
echo implode(', ', $arr) . "\n";
}
function all_sequences($total, $num, $start = 1) {
if ($num == 1) {
return array($total);
}
$max = lowest_maximum($start, $num);
$limit = (int)(($total - $max)/$num) + $start;
$ret = array();
if ($num == 2) {
for ($i = $start; $i <= $limit; $i++) {
$ret[] = array($i, $total - $i);
}
} else {
for ($i = $start; $i <= $limit; $i++) {
$sub = all_sequences($total - $i, $num - 1, $i + 1);
foreach ($sub as $arr) {
array_unshift($arr, $i);
$ret[] = $arr;
}
}
}
return $ret;
}
function lowest_maximum($start, $num) {
return sum_linear($num) + ($start - 1) * $num;
}
function sum_linear($num) {
return ($num + 1) * $num/2;
}
आउटपुट:
इस के
All sequences:
1, 2, 3, 8
1, 2, 4, 7
1, 2, 5, 6
1, 3, 4, 6
2, 3, 4, 5
एक कार्यान्वयन सभी दृश्यों हो और आकस्मिक एक का चयन करने के लिए किया जाएगा। इसका लाभ सभी संभव संयोजनों को समान रूप से भारित करने का लाभ है, जो आप जो कर रहे हैं उसके लिए उपयोगी या आवश्यक हो सकता है या नहीं।
यह बड़े योग या बड़ी संख्या में तत्वों के साथ अनावश्यक हो जाएगा, इस मामले में उपर्युक्त एल्गोरिदम को $start
से $limit
से प्रत्येक मान के बजाय श्रेणी में एक यादृच्छिक तत्व वापस करने के लिए संशोधित किया जा सकता है।
@Russell कोड नमूना देखें। – cletus
धन्यवाद क्लेटस। यह एक शर्म की बात है कि मैं केवल एक बार आप को ऊपर उठा सकता हूं। –
यदि मैं सही ढंग से पढ़ता हूं, तो यह डुप्लीकेट के बिना एक semirandomly वितरित श्रृंखला उत्पन्न करता है। मुझे लगता है कि अगर कई उत्पन्न अनुक्रमों के मूल्यों की साजिश करके इसका परीक्षण किया जाता है, तो उनके वितरण में डुबकी/गांठ दिखाई दे सकते हैं। मैंने एक ऐसा जवाब दिया है जो ऐसा नहीं करना चाहिए, लेकिन स्वीकार्य रूप से मूल्य बदल सकते हैं जब किसी को वास्तविक रूप से बदलने की आवश्यकता नहीं होती है। – strainer