मेरे पास एक रेखीय समीकरण है:
vt = v1*x1 + v2*x2 + v3*x3
vt, v1, v2, v3 0 और 1. के बीच के मानों के साथ स्केलर हैं। X1, x2 और x3 के एक सेट (कोई भी सेट ठीक रहेगा) को उत्पन्न करने का सबसे अच्छा तरीका क्या है जो उपरोक्त समीकरण को पूरा करता है। और भी संतुष्ट
x1>0
x2>0
x3>0
मेरे पास vt, v1, v2 और v3 के कुछ हज़ार सेट हैं, इसलिए मुझे X1, x2 और x3 प्रोग्रामेटिक रूप से जेनरेट करने में सक्षम होना चाहिए।
उत्तर:
जवाब के लिए 3 № 1दो तरीके हैं जिनसे आप यह देख सकते हैं:
- उस विधि से जो आपने अपने पद में समर्पित की है। बेतरतीब ढंग से उत्पन्न
x1
तथाx2
और यह सुनिश्चित करेंvt < v1*x1 + v2*x2
, फिर आगे बढ़ें और हल करेंx3
. - में यह सूत्रबद्ध करें रैखिक कार्यक्रम। एक रैखिक कार्यक्रम मूल रूप से समीकरणों की एक प्रणाली को हल कर रहा है जो असमानता या समानता की बाधाओं के अधीन हैं। दूसरे शब्दों में:
जैसे, हम आपकी समस्या का अनुवाद कर सकते हैंरैखिक प्रोग्रामिंग समस्या। "अधिकतम" कथन वह है जिसे उद्देश्य फ़ंक्शन के रूप में जाना जाता है - जो आप पूरा करने का प्रयास कर रहे हैं उसका समग्र लक्ष्य। रैखिक प्रोग्रामिंग समस्याओं में, हम इस उद्देश्य को कम करने या अधिकतम करने की कोशिश कर रहे हैं। ऐसा करने के लिए, हमें अंदर देखी गई विषमताओं को पूरा करना चाहिए का विषय है शर्त। आमतौर पर, इस कार्यक्रम का प्रतिनिधित्व किया जाता है कानूनी फॉर्म, और इसलिए प्रत्येक चर पर बाधाएं सकारात्मक होनी चाहिए।
अधिकतम स्थिति मनमानी हो सकती है क्योंकि आप उद्देश्य के बारे में परवाह नहीं करते हैं। आप बस किसी भी समाधान के बारे में परवाह करते हैं। इस संपूर्ण प्रतिमान को प्राप्त किया जा सकता है linprog
MATLAB में। आपको किस तरह से सावधान रहना चाहिए linprog
अधिकृत है। वास्तव में, उद्देश्य है कम से कम के बजाय अधिकतम। हालाँकि, यह सुनिश्चित करने के अपवाद हैं कि सभी चर सकारात्मक हैं। हमें वह कोड खुद में लाना होगा।
मनमाने उद्देश्य के संदर्भ में, हम बस कर सकते हैं x1 + x2 + x3
। जैसे की, c = [1 1 1]
। हमारी समानता बाधा है: v1*x1 + v2*x2 + v3*x3 = vt
। हमें यह भी सुनिश्चित करना चाहिए x
सकारात्मक है। इसे कोड करने के लिए, हम जो कर सकते हैं वह एक छोटे से स्थिरांक का चयन करना है ताकि सभी मूल्य x
इस मूल्य से अधिक हैं। अभी, linprog
सख्त असमानताओं का समर्थन नहीं करता (अर्थात x > 0
) और इसलिए हमें यह चाल चलकर इसे दरकिनार करना होगा इसके अलावा, यह सुनिश्चित करने के लिए कि मूल्य सकारात्मक हैं, linprog
मान लेता है कि Ax <= b
। इसलिए, एक सामान्य ट्रिक जिसका उपयोग किया जाता है, वह है असमानता को नकारना x >= 0
, और इसलिए यह इसके बराबर है -x <= 0
। यह सुनिश्चित करने के लिए कि मूल्य गैर-शून्य हैं, हम वास्तव में करेंगे: -x <= -eps
, कहा पे eps
एक छोटा स्थिर है। हालाँकि, जब मैं प्रयोग कर रहा था, तो इस तरह से करने से, दो चर एक ही समाधान हो जाते हैं। जैसे, मैं जो सलाह दूंगा वह अच्छा समाधान उत्पन्न करने के लिए है जो हर बार यादृच्छिक हो, चलो आकर्षित करें b
जैसा कि आपने कहा एक समान यादृच्छिक वितरण से। इसके बाद हम इस समस्या को हल करना चाहते हैं।
इसलिए, हमारी असमानताएं हैं:
-x1 <= -rand1
-x2 <= -rand2
-x3 <= -rand3
rand1, rand2, rand3
तीन बेतरतीब ढंग से उत्पन्न संख्याएं हैं जो बीच में हैं 0
तथा 1
। मैट्रिक्स के रूप में, यह है:
[-1 0 0][x1] [-rand1]
[0 -1 0][x2] <= [-rand2]
[0 0 -1][x3] [-rand3]
अंत में, पहले से हमारी समानता बाधा है:
[v1 v2 v3][x1] [vt]
[x2] =
[x3]
अब, उपयोग करने के लिए linprog
, आप ऐसा करेंगे:
X = linprog(c, A, b, Aeq, beq);
c
एक गुणांक सरणी है जिसे उद्देश्य के लिए परिभाषित किया गया है। इस मामले में, इसे परिभाषित किया जाएगा [1 1 1]
, A
तथा b
असमानता बाधाओं के लिए परिभाषित मैट्रिक्स और स्तंभ वेक्टर है Aeq
तथा beq
मैट्रिक्स और स्तंभ वेक्टर समानता बाधाओं के लिए परिभाषित किया गया है। X
इस प्रकार हमें समाधान के बाद देना होगा linprog
अभिसरण (i.e.) x1, x2, x3
)। जैसे, आप यह करेंगे:
A = -eye(3,3);
b = -rand(3,1);
Aeq = [v1 v2 v3];
beq = vt;
c = [1 1 1];
X = linprog(c, A, b, Aeq, beq);
उदाहरण के तौर पर मान लीजिए v1 = 0.33, v2 = 0.5, v3 = 0.2
, तथा vt = 2.5
। इसलिए:
rng(123); %// Set seed for reproducibility
v1 = 0.33; v2 = 0.5; v3 = 0.2;
vt = 2.5;
A = -eye(3,3);
b = -rand(3,1);
Aeq = [v1 v2 v3];
beq = vt;
c = [1 1 1];
X = linprog(c, A, b, Aeq, beq);
मुझे मिला:
X =
0.6964
4.4495
0.2268
यह सत्यापित करने के लिए कि यह बराबर है vt
, हम करेंगे:
s = Aeq*X
s = 2.5000
ऊपर बस करता है v1*x1 + v2*x2 + v3*x3
। चीजों को आसान बनाने के लिए एक डॉट उत्पाद रूप में इसकी गणना की जाती है X
एक कॉलम वेक्टर है और v1, v2, v3
पहले से सेट हैं Aeq
और एक पंक्ति वेक्टर है।
जैसे, या तो रास्ता अच्छा है, लेकिन कम से कम linprog
, जब तक आप संतुष्ट होने के लिए उस स्थिति को प्राप्त नहीं करते हैं, तब तक आपको लूपिंग नहीं करनी है!
एक छोटी सी चेतावनी जिसे मैं उपर्युक्त दृष्टिकोण में बताना भूल गया था कि आपको यह सुनिश्चित करने की आवश्यकता है vt >= v1*rand1 + v2*rand2 + v3*rand3
अभिसरण सुनिश्चित करने के लिए। चूंकि आपने ऐसा कहा है v1,v2,v3
के बीच बंधे हैं 0
तथा 1
सबसे बुरा मामला है जब v1,v2,v3
सभी 1 के बराबर हैं। जैसे, हमें वास्तव में यह सुनिश्चित करने की आवश्यकता है vt > rand1 + rand2 + rand3
। अगर यह है नहीं मामला, तो बस के प्रत्येक मूल्य ले rand1, rand2, rand3
, और से विभाजित करें (rand1 + rand2 + rand3) / vt
। इस प्रकार, यह सुनिश्चित करेगा कि कुल योग बराबर होगा vt
यह मानते हुए कि सभी भार 1 हैं, और यह रैखिक कार्यक्रम को ठीक से परिवर्तित करने की अनुमति देगा।
यदि आप "टी" नहीं करते हैं, तो समाधान को असमानता की स्थिति के कारण निर्धारित नहीं किया जाएगा b
, और आप जीत गए "सही जवाब नहीं मिला। बस कुछ सोचा के लिए भोजन! जैसे, इस के लिए करते हैं b
दौड़ने से पहले linprog
if sum(-b) > vt
b = b ./ (sum(-b) / vt);
end
सौभाग्य!