روش سیمپلکس (Simplex) | به زبان ساده
الگوریتم سیمپلکس (Simplex Algorithm) روشی برای به دست آوردن جواب بهینه یک تابع هدف خطی با دستگاهی از قیود است. این الگوریتم با یک رأس پایه از ناحیه شدنی (Feasible Region) شروع میشود و برای رئوس مجاور ادامه پیدا میکند. روش سیمپلکس تا رسیدن به جواب بهینه ادامه مییابد. ناحیهای که به قیود سیستم محدود میشود، ناحیه شدنی (Feasible Region) نامیده میشود. این ناحیه، مقادیر ممکن متغیرهایی را نشان میدهد که در همه قیود صدق میکنند. برای آنکه برنامهریزی خطی قابل اعمال باشد، ناحیه شدنی باید یک چندبر یا چندسقفی محدب (Convex Polytope) باشد (در حالت دوبعدی، یک چندضلعی محدب و در حالت سهبعدی، یک چندوجهی محدب و…). برای آشنایی بیشتر با ناحیه شدنی، به آموزش «برنامهریزی خطی در متلب» مراجعه کنید.
روش سیمپلکس مراحل و قواعد زیادی دارد. قبل از بیان الگوریتم کلی روش سیمپلکس، با یک مثال این مراحل و قواعد را بررسی میکنیم.
مثال ساده روش سیمپلکس
دستگاه قیود زیر را در نظر بگیرید:
میخواهیم تابع هدف زیر را با توجه به این قیود بیشینه کنیم:
حل: روش سیمپلکس با تبدیل قیود و توابع هدف به یک دستگاه معادلات آغاز میشود. این کار را میتوان با معرفی متغیرهای جدیدی به نام «متغیر لَنگی» یا «متغیر کمکی» یا «متغیر کمبود» (Slack Variables) انجام داد. متغیرهای کمکی اختلاف یا اسلک مثبت بین سمت چپ یک نامعادله و سمت راست آن را نشان میدهند.
بنابراین، نامعادله
به تساوی زیر تبدیل میشود:
به طور مشابه، نامعادله
با تساوی زیر معادل است:
علاوه بر متغیرهای کمکی، متغیر را نیز تعریف میکنیم که مقدار تابع هدف را نشان میدهد. در نتیجه، میتوان نوشت:
معادلات بالا منجر به دستگاه معادلات زیر خواهد شد:
دستگاه معادلات بالا را به فرم ماتریس افزوده مینویسیم:
این ماتریس نشان میدهد که همه متغیرهای این دستگاه (شامل ، و ) بزرگتر از یا مساوی با صفر هستند. ضرایب متغیرهای و در سطر ، صفر است. این متغیرها متغیرهای اساسی (Basic Variables) نامیده میشوند. متغیرهای و ضرایب غیرصفری در سطر دارند و متغیرهای غیراساسی (Non-basic Variables) نامیده میشوند. در هر لحظه از الگوریتم، جواب اساسی با صفر قرار دادن متغیرهای غیراساسی به دست میآید. بنابراین، اکنون جواب اساسی به صورت زیر است:
به تأثیر افزایش مقادیر متغیرهای غیراساسی روی متغیر توجه کنید. افزایش هر یک از متغیرهای و سبب افزایش خواهد شد، زیرا ضرایب و در سطر منفی است. در نتیجه، این جواب بهینه نیست.
تکرار روش سیمپلکس شامل تبادل متغیرهای اساسی و متغیرهای غیراساسی با استفاده از عملیاتی سطری مقدماتی ماتریسی است. در هر مرحله از فرایند، یک متغیر غیراساسی در سطر حذف میشود و یک متغیر اساسی دیگر جای آن را به عنوان متغیر غیراساسی میگیرد. این سطر، «لولا» (Pivot) نامیده میشود.
فرض کنید از سطر حذف شده باشد. این کار را میتوان توسط سطر یا انجام داد.
حالت ۱: حذف در سطر توسط سطر :
در این لولا، متغیر به عنوان یک متغیر اساسی وارد میشود و متغیر خارج میشود تا یک متغیر غیراساسی شود. اکنون را از سطر حذف میکنیم:
که منجر به جواب اساسی زیر خواهد شد:
این جواب نشدنی است، زیرا منجر به منفی شدن یکی از متغیرها شده است.
حالت ۲: حذف در سطر توسط سطر
در این لولا، متغیر به عنوان یک متغیر اساسی وارد شده و متغیر به یک متغیر غیراساسی تبدیل شده و خارج میشود. اکنون را از سطر حذف میکنیم:
در نتیجه، جواب اساسی زیر را خواهیم داشت:
این جواب قابل قبول است، اما بهینه نیست؛ زیرا یک ضریب منفی در سطر وجود دارد. این بدین معنی است که با افزایش میتوان را زیاد کرد. یک لولای دیگر برای یافتن جواب بهینه لازم است.
خوشبختانه میتوان با مشاهده نسبت درایه ستون سمت راست ماتریس افزوده به ضریب متغیر ورودی، مشاهده کرد که کدام لولا منجر به یک جواب شدنی خواهد شد. متغیر را به عنوان متغیر ورودی در نظر گرفته و نسبتها را محاسبه میکنیم:
برای متغیر وارد شده ، نسبت برای سطر برابر با و برای سطر برابر با است. انتخاب سطری که نسبت را کمینه میکند، تضمین خواهد کرد که لولا منجر به یک جواب شدنی شود. بنابراین، سطر را باید به عنوان سطر لولا انتخاب کرد.
با حذف در سطر با استفاده از سطر ، داریم:
حذف در سطر نیز به صورت زیر است:
در نتیجه، جواب اساسی زیر را خواهیم داشت:
این جواب باید بهینه باشد، زیرا هر افزایش در متغیرهای غیراساسی و سبب کاهش در خواهد شد. بنابراین، مقدار بیشینه تابع هدف برابر است با:
روش سیمپلکس برای بیشینهسازی
این نسخه از روش سیمپلکس برای یک مسئله بیشینهسازی با همه قیود (جز برای قیود نامنفی) مقادیر بیشینه را به دست خواهد داد. فرم ماتریسی الزامات به صورت زیر است:
که در آن، برداری شامل ضرایب تابع هدف، یک بردار شامل متغیرهای مسئله، یک ماتریس شامل ضرایب قیود و یک بردار شامل مقادیر بیشینه این قیود است. برای استفاده از روش سیمپلکس برای بهینهسازی، گامهای زیر را انجام دهید.
- با معرفی متغیرهای کمکی و متغیر قیود و تابع هدف را به یک دستگاه معادلات تبدیل کنید.
- دستگاه معادلات را به فرم ماتریس افزوده در آورید. معادله تابع هدف باید به سطر برود.
- یکی از متغیرهای غیراساسی را برای آنکه متغیر ورودی باشد، انتخاب کنید.
- با محاسبه نسبت درایه ستون سمت راست ماترس افزوده بر ضریب متغیر وارد شونده برای هر سطر، سطر لولا را انتخاب کنید. سطر لولای صحیح، نسبت را کمینه خواهد کرد. البته این نسبت باید مثبت باشد.
- اگر همه ضرایب متغیرهای غیراساسی در سطر مثبت باشند، آنگاه جواب بهینه را خواهیم داشت. در غیر این صورت، یک متغیر اساسی را انتخاب کنید که در سطر ضریب منفی داشته باشد، تا متغیر ورودی بعدی بوده و در نتیجه، لولا دوباره باید یک جواب شدنی دیگر را پیدا کند. عملیات لولا را تا جایی ادامه دهید که جواب بهینه به دست آید.
روش سیمپلکس برای کمینهسازی
این نسخه از روش سیمپلکس برای یک مسئله کمینهسازی با همه قیودی که مقدار کمینه را نتیجه میدهند معتبر است. در فرم ماتریسی، الزامات اینگونه است:
که در آن، برداری شامل ضرایب تابع هدف، برداری شامل متغیرهای مسئله، یک ماتریس شامل ضرایب قیود و یک بردار شامل مقادیر کمینه این قیود است. برای پیادهسازی این الگوریتم، به صورت زیر عمل میکنیم.
- ضرایب قیود و تابع هدف را در ماتریس افزوده قرار دهید. ضرایب تابع هدف باید به سطر زیرین بروند.
- ماتریس را ترانهاده کنید.
- این ماتریس جدید، دوگان مسئله بیشینهسازی است. دستگاه جدید قیود و تابع هدف را بنویسید. این مسئله متغیرهای متفاوتی نسبت به مسئله اصلی دارد.
- از روش سیمپلکس برای بیشینهسازی استفاده کنید تا مقدار بیشینه را به دست آورید. مقدار بیشینه همان مقدار کمینه مسئله اصلی است. ضرایب متغیرهای کمکی سطر متناظر با مقادیر متغیرهای مسئله اصلی هستند.
مثال دوگان روش سیمپلکس
دستگاه قیود زیر را در نظر بگیرید:
تابعی که میخواهیم آن را کمینه کنیم به صورت زیر است:
این مسئله را میتوان به فرم دیگر بیشینهسازی بالا نشان داد، اما مسئلهای در یافتن جواب اساسی اول اتفاق میافتد: برابر قرار دادن متغیرهای ، و با منجر به یک جواب نشدنی با متغیرهای کمکی میشود که مقدار آنها منفی است. روش سیمپلکس باید با جواب شدنی آغاز شود، بنابراین، مفید نخواهد بود. روش M بزرگ راهحلی برای این مشکل ارائه میدهد، اما روش بسیار سادهتری برای این مسئله وجود دارد.
یک دوگان برای این مسئله، را میتوان با ترانهادن ضرایب نوشت. برای این کار باید ضرایب قیود را در یک ماتریس افزوده قرار داد. همچنین باید ضرایب تابع هدف را در سطر زیرین، با یک در قسمت راست قرار داد:
حاصل ترانهادن درایههای ماتریس به شکل زیر است:
توجه کنید که ممکن است به تقسیم سطر دوم بر ۳ وسوسه شوید، اما باید دقت کرد که این کار موجب بر هم خوردن تقارنی خواهد شد که برای بازگشتن به مسئله اصلی لازم است.
اکنون دستگاهی از قیود و تابع هدف داریم که باید بیشینه شود. قیود به صورت زیر هستند:
و باید تابع هدف زیر را بیشینه کنند:
اکنون میتوانیم از روش سیمپلکس برای پیدا کردن جواب بهینه استفاده کنیم:
را در سطر وارد میکنیم:
تمام ضرایب در سطر مثبت هستند، بنابراین این جواب بهینه است. مقدار بیشینه در قسمت بالای سمت راست (یعنی )، برابر با مقدار کمینه برای مسئله اصلی است. البته متغیرهای ، و برابر با متغیرهای مسئله اصلی نیستند. خوشبختانه، مقادیر متغیرهایی که مسئله اصلی را کمینه میکنند، متناظر با ضرایب متغیرهای کمکی در سطر هستند.
بنابراین، مقادیر مسئله اصلی که تابع هدف را کمینه میکنند، به صورت زیر است:
حالتهای خاص روش سیمپلکس
روش سیمپلکس ممکن است گاهی منجر به نتایج غیرقابل پیشبینی شود. ممکن است مسئله برنامهریزی خطی بینهایت جواب داشته باشد یا اصلاً جوابی نداشته باشد. در ادامه، این حالتهای خاص را بررسی میکنیم. همانطور که قبلاً گفتیم، یک مسئله بهینهسازی خطی را که قیود کمینه دارد، نمیتوان با روش سیمپلکس حل کرد. دلیل این امر آن است که جواب اساسی اولیه نشدنی است.
مثالی از عدم کارایی روش سیمپلکس
دستگاه قیود زیر را در نظر بگیرید:
میخواهیم تابع هدف زیر را کمینه کنیم:
نشان دهید این کار را نمیتوان با روش سیمپلکس معمولی انجام داد.
پاسخ: این مسئله را میتوان با یک دوگان یا آزمایش رئوس ناحیه شدنی حل کرد، اما روش سیمپلکس را برای آن بررسی میکنیم. از آنجا که قیود، قیود کمینه هستند، متغیرهای کمکی باید ضرایب منفی داشته باشند. علاوه بر این، تابع هدف یک کمینهسازی است که میتوان آن را یک مسئله بیشینهسازی در نظر گرفت. با اعمال روش سیمپلکس، ماتریس اولیه به صورت زیر خواهد بود:
این ماتریس اولیه جواب نشدنی و را نشان میدهد. اگر جواب اساسی اولیه نشدنی باشد، روش سیمپلکس نتیجه بامعنی نخواهد داشت.
گاهی اوقات میتوان مسئله را با دوگان آن حل کرد، اما نه برای وقتی که مسئله شامل ترکیبی از قیود کمینه و بیشینه باشد.
مثالی از عدم کارایی دوگان روش سیمپلکس
دستگاه قیود زیر را در نظر بگیرید.
میخواهیم تابع زیر کمینه شود:
نشان دهید این کار را نمیتوان با استفاده از روش سیمپلکس معمولی یا روش دوگان انجام داد.
پاسخ: این مسئله را به فرم یک ماتریس سیمپلکس مینویسیم و میبینیم که یک جواب اساسی اولیه نشدنی دارد:
با نوشتن دوگان مسئله به صورت یک ماتریس سیمپلکس نیز یک جواب اساسی اولیه نشدنی خواهیم داشت:
وقتی یک جواب اساسی اولیه نشدنی است، میتوان از روش M بزرگ استفاده کرد. ایده پشت این روش، معرفی متغیرهای مصنوعی یا ساختگی (Artificial Variables) برای جابهجایی جواب به ناحیه شدنی است. برخلاف متغیرهای کمکی، باید مقدار این متغیرهای ساختگی در جواب نهایی صفر باشد.
روش M بزرگ
- این روش برای هر مسئله برنامهریزی خطی که با فرمهای قبل سازگار نیست، مطابقت دارد. همچنین، برای مسائلی که شامل محدودیتهایی به صورت تساوی هستند، مناسب است.
- متغیرهای کمکی و متغیر را مانند روش سیمپلکس پایه تعیین کرده و یک ماتریس سیمپلکس را ایجاد کنید. برای هر متغیر کمکی که دارای مقدار منفی در جواب اساسی اولیه است، یک متغیر ساختگی مجزا را به آن محدودیت اضافه کنید. همچنین یک متغیر ساختگی مشخص را به هر قید تساوی اضافه کنید. متغیرهای ساختگی با ضریب در هر سطر محدودیت شروع میشوند. در سطر تابع هدف، هر متغیر مصنوعی با ضریب یکسان شروع می شود. یک مقدار ثابت مثبت دلخواه را نشان میدهد.
- اگر مسئله کمینهسازی باشد، آنگاه ضرایب سطر تابع هدف قرینه میشوند و هرف بیشینه کردن خواهد بود.
- با لولاها و با استفاده از یک متغیر کمکی منفی به عنوان یک متغیر خروجی و یک متغیر ساختگی به عنوان متغیر ورودی، جواب را به ناحیه شدنی جابهجا کنید.
- وقتی جواب اساسی در ناحیه شدنی قرار گرفت، مانند روش سیمپلکس کار را ادامه دهید.
- وقتی در حال اجرای روش سیمپلکس هستید، باید مطمئن باشید که عناصر سمت راست ماتریس مثبت هستند. اگر یک عنصر در سمت راست مثبت نباشد، آن سطر را در ضرب کنید تا مثبت شود. اگر یک عنصر در سمت راست ماتریس باشد، آنگاه مطمئن شوید ضریب متغیر اساسی در آن سطر مثبت است.
- متغیر وارد شونده را با مشاهده ضریب در سطر انتخاب کنید که از همه منفیتر است. سطرهای لولا را با انتخاب سطری که نسبت عنصر سمت راست ماتریس افزوده را به ضریب متغیر وارد شونده کمینه میکند، انتخاب کنید. این نسبت باید نامنفی بوده و ضریب متغیر وارد شونده در سطر لولا باید مثبت باشد.
- یک جواب بهینه نمیتواند شامل هرگونه متغیر ساختگی باشد. اگر سطر ماتریس شامل ضرایب نامنفی نباشد، و جواب شامل یک متغیر ساختگی باشد، آنگاه مسئله جواب نخواهد داشت.
مثال اول روش M بزرگ
دستگاه قیود زیر را در نظر بگیرید.
میخواهیم تابع زیر را کمینه کنیم:
با توجه به مثال قبل، میدانیم که قید سوم منجر به جواب نشدنی میشود. برای جبران این موضوع، متغیر ساختگی را معرفی میکنیم. در تابع هدف، این متغیر دارای ضریب خواهد بود. یک مقدار ثابت بزرگ دلخواه است. قیود و تابع هدف جدید به صورت زیر خواهند بود:
و به فرم ماتریسی، داریم:
هدف نخست در روش M بزرگ، جابهجایی مسئله به ناحیه شدنی است. جواب اساسی کنونی دارای است. این متغیر، متغیر خروجی خواهد بود و متغیر ساختگی ، متغیر ورودی است:
اکنون جواب در ناحیه شدنی است و تمام متغیرهای اساسی مثبت هستند:
واضح است که این جواب صحیح نیست، زیرا شامل یک متغیر ساختگی غیرصفر است. علاوه بر این، ضرایب منفی در سطر وجود دارد. اکنون میتوان از روش M بزرگ مانند سیمپلکس استفاده کرد. هدف جدید، آوردن متغیرهای با ضرایب منفی به سطر است. از آنجا که منفیترین ضریب در سطر است، ابتدا این متغیر وارد خواهد شد. سطری که نسبت درایه ستون سمت راست و ضریب را کمینه میکند، است، بنابراین، به این سطر وارد خواهد شد:
این جواب، دیگر شامل متغیر ساختگی نیست، اما هنوز هم بهینه نیست، زیرا ضریب سطر منفی است. باید متغیر بعدی برای ورود باشد. حداقل نسبت مثبت برای این متغیر در سطر است:
اکنون باید متغیر ورودی باشد و تنها سطر با نسبت مثبت است:
واضح است که جواب بهینه برابر خواهد بود با:
مثال دوم روش M بزرگ
شرکتی در حال برنامهریزی برای تنظیم ساعت کاری هفته آینده کاگرانش است. در خط مونتاژ، بهروز ۵ واحد در ساعت مونتاژ میکند و هنگامی که در خط بستهبندی است، ۱۰ واحد در ساعت بستهبندی میکند. فردین فقط روی خط مونتاژ کار میکند و ۴ واحد در ساعت مونتاژ میکند. دستمزد بهروز ۱۲ دلار در ساعت و دستمزد فردین ۹ دلار است. شرکت تا پایان هفته باید حداقل ۲۰۰ واحد مونتاژ شده و بستهبندی شده را تحویل دهد و میتواند حداکثر ۴۰ ساعت به هر کدام اختصاص دهد. این شرکت برای به حداقل رساندن دستمزد کارگران چگونه باید برنامهریزی کند؟
پاسخ: این مسئله را میتوان با روشهای سادهتری حل کرد، اما در اینجا از روش M بزرگ استفاده میکنیم تا روش کار با قیود مختلف را بررسی کنیم.
فرض کنید و ، به ترتیب، تعداد ساعتهایی باشند که بهروز و فردین در خط مونتاژ کار میکنند. همچنین، تعداد ساعتهایی است که بهروز در خط بستهبندی کار میکند. هرکدام از این دو نفر، حداکثر میتوانند ۴۰ ساعت کار کنند. بنابراین، قیود زیر را خواهیم داشت:
شرکت نمیخواهد وقتی واحد مونتاژ شده برای بستهبندی وجود ندارد، وقتی تلف شود. بنابراین، تعداد واحدهای مونتاژ شده باید برابر با تعداد واحدهای بستهبندی شده باشد. این گفته را میتوان به صورت زیر نوشت:
تعداد واحدهای مونتاژ شده و باید حداقل ۲۰۰ باشد. این موضوع را میتوان با قیود زیر نوشت:
در نتیجه، دستگاه قیود زیر را خواهیم داشت:
تابع هدف به صورت زیر است:
دستگاه قیود و تابع هدف را به یک ماتریس سیمپلکس تبدیل میکنیم:
جواب اساسی کنونی نشدنی است:
از آنجا که یک مقدار نشدنی دارد، سطری که شامل آن است، به یک متغیر ساختگی نیاز دارد. قید تساوی نیز به یک متغیر ساختگی نیاز دارد. این متغیرهای ساختگی دارای ضریب در سطر هستند:
برای جابهجا کردن جواب به ناحیه شدنی، متغیر خارج شونده و متغیر وارد شونده خواهد بود. لولا را میتوان در سطر انجام داد:
متغیر ساختگی دیگر نیز باید به جواب اساسی جابهجا شود.
اکنون الگوریتم را مانند روش سیمپلکس ساده اجرا میکنیم. هدف، حذف ضرایب منفی سطر است. از آنجا که هر مقدار ثابت مثبت بزرگ دلخواهی میتواند باشد، منفیترین ضریب در سطر است. بنابراین، متغیر وارد شونده خواهد بود. انتخاب سطر لولا نسبت به روش سیمپلکس ساده چالش بیشتری دارد.
مشاهده میکنیم که هر مقدار در سمت راست سطرهای قیود به جز مقدار سطر مثبت است. در این سطر، سمت راست است و متغیر اساسی آن، ، دارای یک ضریب مثبت است. دو مورد زیر مهم هستند:
- مقادیر سمت راست سطرهای قیود مثبت هستند، یا
- اگر مقدار سمت راست باشد، آنگاه ضریب متغیر اساسی در آن سطر مثبت است.
این امر انتخاب صحیح سطر لولا را تضمین خواهد کرد. سطر لولا با انتخاب سطری که در آن، نسبت عنصر سمت راست ماتریس افزوده به ضریب متغیر وارد شونده کمینه است، انتخاب میشود و ضریب متغیر وارد شونده مثبت است.
بنابراین، حداقل نسبت برای متغیر وارد شونده از سطر است. این سطر، سطر لولا خواهد بود:
اکنون، منفیترین ضریب در سطر است. بنابراین، متغیر وارد شونده خواهد بود. سطر دوباره به عنوان سطر لولا انتخاب نخواهد شد، زیرا یک ضریب منفی برای این متغیر دارد. سطری که نسبت را کمینه میکند، سطر است:
حال، منفیترین ضریب در سطر است. متغیر وارد شونده و نسبت کمینهکننده در سطر خواهد بود:
اکنون منفیترین ضریب در سطر است. متغیر وارد شونده و نسبت کمینهساز در سطر است:
با مثبت بودن همه ضرایب در سطر و نبود متغیر ساختگی در جواب، جواب بهینه است و به صورت زیر خواهد بود:
بنابراین، شرکت باید از بهروز به مدت ۸ ساعت در خط مونتاژ و ۲۰ ساعت در خط بستهبندی استفاده کند. همچنین، فردین باید ۴۰ ساعت در خط مونتاژ کار کند. این منجر به ۹۶۹ دلار برای یک هفته میشود.
روش سیمپلکس در متلب
برای پیادهسازی روش سیمپلکس در متلب، میتوانید از برنامه زیر استفاده کنید.
1function tab = nma_simplex(A,b,c,debug)
2%function [A,b,c]=nma_simplex(A,b,c)
3%This function implments the simplex matrix algorithm.
4%It accepts A_eq and b_eq and c as defined in standard
5%documentation and generates all the simplex tableaus, and
6%returns the final tableau which the user can read from it the
7%minimum value of the objective function and the optimal x vector
8%directly.
9
10%
11%It runs both phase one and phase two automatically.
12%
13%The input is
14%
15%A: This is the Ax=b matrix. This is for simplex standard
16% form only. The caller must convert all inequalites to
17% equalities first by using slack and suprluse variables. This
18% is what is called the Aeq matrix in Matlab documenation.
19% This function does not support Ax<b form. A has to be in
20% standard form
21%
22%b: Vector. This is the right hand side of Ax=b.
23%
24%c: Vector. This is from minimize J(x) = c'x. As defined in
25% standard Matlab documentations.
26%
27%debug: flag. Set to true to see lots of internal steps.
28%
29%Returns:
30%
31%This function returns the final tableau. It has the form
32%
33% [ A | b ]
34% [ c | J ]
35%
36% Version 5/12/2016
37% by Nasser M. Abbasi
38% Free for use.
39
40validate_input(A,b,c);
41
42[A,b] = make_phase_one(A,b,debug);
43tab = simplex(A,b,c,debug,'phase two');
44end
45%==========================
46function [A,b] = make_phase_one(A,b,debug)
47[m,n] = size(A);
48tab = zeros(m+1,n+m+1);
49tab(1:m,1:n) = A;
50tab(end,n+1:end-1) = 1;
51tab(1:m,end) = b(:);
52tab(1:m,n+1:n+m) = eye(m);
53
54if debug
55 fprintf('>>>>Current tableau [phase one]\n');
56 disp(tab);
57end
58
59
60
61for i = 1:m %now make all entries in bottom row zero
62 tab(end,:) = tab(end,:)-tab(i,:);
63end
64
65tab = simplex(tab(1:m,1:n+m),tab(1:m,end),tab(end,1:n+m),...
66 debug,'phase one');
67%if tab(end,end) ~=0
68% error('artificial J(x) is not zero at end of phase one.');
69%end
70
71A = tab(1:m,1:n);
72b = tab(1:m,end);
73
74end
75%=================================
76function tab = simplex(A,b,c,debug,phase_name)
77[m,n] = size(A);
78tab = zeros(m+1,n+1);
79tab(1:m,1:n) = A;
80tab(m+1,1:n) = c(:);
81tab(1:m,end) = b(:);
82
83keep_running = true;
84while keep_running
85 if debug
86 fprintf('***********************\n');
87 fprintf('Current tableau [%s] \n',phase_name);
88 disp(tab);
89 end
90
91 if any(tab(end,1:n)<0)%check if there is negative cost coeff.
92 [~,J] = min(tab(end,1:n)); %yes, find the most negative
93 % now check if corresponding column is unbounded
94 if all(tab(1:m,J)<=0)
95 error('problem unbounded. All entries <= 0 in column %d',J);
96 %do row operations to make all entries in the column 0
97 %except pivot
98 else
99 pivot_row = 0;
100 min_found = inf;
101 for i = 1:m
102 if tab(i,J)>0
103 tmp = tab(i,end)/tab(i,J);
104 if tmp < min_found
105 min_found = tmp;
106 pivot_row = i;
107 end
108
109
110 end
111 end
112 if debug
113 fprintf('pivot row is %d\n',pivot_row);
114 end
115 %normalize
116 tab(pivot_row,:) = tab(pivot_row,:)/tab(pivot_row,J);
117 %now make all entries in J column zero.
118 for i=1:m+1
119 if i ~= pivot_row
120 tab(i,:)=tab(i,:)-sign(tab(i,J))*...
121 abs(tab(i,J))*tab(pivot_row,:);
122 end
123 end
124 end
125 if debug %print current basic feasible solution
126 fprintf('current basic feasible solution is\n');
127 disp(get_current_x());
128 end
129 else
130 keep_running=false;
131 end
132end
133
134 %internal function, finds current basis vector
135 function current_x = get_current_x()
136 current_x = zeros(n,1);
137 for j=1:n
138 if length(find(tab(:,j)==0))==m
139 idx= tab(:,j)==1;
140 current_x(j)=tab(idx,end);
141 end
142 end
143 end
144end
145%==========================
146function validate_input(A,b,c)
147if ~ismatrix(A)
148 error('A must be matrix');
149end
150
151if ~isvector(b)
152 error('b must be vector');
153end
154if ~isvector(c)
155 error('c must be vector');
156end
157
158
159
160[m,n]=size(A);
161if rank(A) <m
162 error('Rank A must be equal to number of rows in A');
163end
164
165if length(b) ~= m
166 error('b must have same size as number of rows of A');
167end
168if length(c) ~= n
169 error('c must have same size as number of columns of A');
170end
171end
در برنامه بالا، تابع هدف به صورت زیر تعریف شده است:
با سلام و احترام کد متلب سیمپلکس برای این نمونه سوال
max z=-8×1+2×2
s.t
x2-x1<6
x1<12
x1+x2<16
x2<8
جواب متفاوتی با حل هدی و اکسل دارد.
امکانش هست راهنمایی فرمایید؟
سلام در عملیات سطری مقدماتی برای صفر کردن x در ماتریس اول در ضریب y سطر 0 اشتباه رخ داده است
R0=7/2R1+R0 میباشد
با سلام،
متن بازبینی و ویرایش شد،
با تشکر از همراهی شما با مجله فرادرس