تلرانس متغیرهای integer در گمز

هدف از حل مدلهای MIP رسیدن به یک جواب شدنی و بهینه است که باید متغیرهای integer دخیل در آن مقادیر صحیحی به خود بگیرند. در پاره ای از اوقات پیش می آید که در خروجی گمز مشاهده می شود که یک متغیر مثلا عددی نزدیک به صفر (مثلا ۳ میلیونم!) به خود گرفته است. این عدد از لحاظ مفهومی احتمالا نامفهوم و غیر کاربردی است. به عنوان مثال وقتی ما یک متغیر صفر و یک تعریف کرده ایم ولی در خروجی مقداری نزدیک به صفر مشاهده می کنیم، از لحاظ ما این امر پذیرفته نیست و فوری به دنبال راه چاره خواهیم گشت.

برای رفع این مشکل ابتدا باید به تلرانس مجاز متغیرهای عدد صحیح دقت کنیم. این تلرانس با آپشنی به نام epint در گمز تعریف شده است. آپشن به صورت دیفالت مقدار بین ۰ تا ۱e-5 را مجاز اعلام می کند. به عبارتی اگر متغیر عدد صحیح مقدار ۳ میلیونم را کسب کرد، گمز بدون ایراد هیچ مشکلی آن را مورد پذیرش قرار می دهد (در حالی که ممکن است منطقی هم نباشد) کاری که ما می توانیم علیه این گزارش گمز انجام دهیم این است که این آپشن را برابر صفر قرار دهیم یعنی epint=0 . در این صورت در صورت وجود جواب شدنی برای مسئله، گمز جواب دقیق عدد صحیح به ما ارائه خواهد داد. که البته ممکن است زمان حل مسئله بیشتر از قبل شود. پس اگر دنبال این جواب هستید حتما مقدار epint را تنظیم کنید.

از طرفی می توان از این آپشن به عنوان نوعی تلرانس مجاز برای متغیرها هم استفاده کرد. به عنوان مثال فردی ممکن است تمایل داشته باشد که برای متغیرهایش تلرانس ۰٫۰۱  در نظر بگیرد (این بستگی به هدف و چرایی مدل و کد دارد).

درباره نویسنده

32 دیدگاه

  1. مهدی

    با سلام و احترام و تشکر بابت پاسخ هایی که تا الان داده اید
    من کدی که مربوط به حالت خاصی از مسئله TSP هست رو ران می کنم. این کار رو هم رو سروری با حدود ۲۰ ترد و ۸۰ گیگ رم ران میکنم ولی متاسفانه به جهت محاسبات زیاد نیازمند رم بیشتری هست و در جایی که ۰٫۶۷% گپ رو نشون میده ارور کم بودن رم رو میده و اجرا رو متوقف می کنه…آیا در گمز روشی وجود دارد که بواسطه اون بشه استفاده از رم رو مدیریت کرد و جلوی توقف کد رو گرفت … اگر زمانش طولانی بشه مسئله ای نیست. مهم اینه که اجرا رو تا آخر بره

    ممنون از بابت پاسخهاتون

    1. محمودی

      سلام
      میتونین از optionهایی نظیر cutoff استفاده کنین. این آپشن به گمز میگه که جوابایی که از یه مقدار مشخص بدتر هستن رو حذف کنه. معمولا خیلی کمک میکنه. مقداری در موردش مطالعه کنین. و بر حسب مسئله خودتون ازش استفاده بکنین. ضمنا تو کانال تلگرام هم مطالبی در این مورد نوشتیم شاید به دردتون بخوره.
      مرسی و خواهش میکنم.

  2. حسین

    سلام. من یک مسأله MILP دارم که تعداد متغیرهای integer زیادی داره. برای حلش از یک کامپیوتر با ۳۲GB رم با CPU هشت هسته‌ای استفاده میکنم. منتها زمان حل طولانیه و از حجم کمی از رم و cpu استفاده میشه. ینی در زمان حل، رم حدود ۱۰ درصد و cpu حدود ۱۵ درصد هستن. میخاستم ببینم راهی هست که از حجم بیشتری از رم و cpu استفاده بشه که سریعتر به جواب برسم. لپ‌تاپم، رم ۴ و cpu چهار هسته‌ای داره؛ این کامپیوتری که برای حل مسأله ازش استفاده میکنم، فقط ۳ برابر سریعتر از لپ‌تاپ جواب میده.
    با تشکر

    1. محمودی

      سلام
      ۳ برابر هم باز هم خوبه! اینجوری نیست که سرعت ها به صورت نمایی تغییر کنه که. همینم خوبه.
      ولی برای افزایش استفاده از cpu میتونین از آپشن زیر استفاده کرد:

      option threads=8;
      

      که ۸ تعداد هسته ها رو نشون میده.

  3. فرنوش پارسی

    سلام
    ممنون از سایت خوبتون
    یک مدل بهینه سازی دارم که یک جمله از تابع هدفش به صورت زیر دارم که میخوام در گمز بزنم ولی چون در معادله فاکتوریل متغیر (c) باید حساب بشه، گمز اجرا نمیکنه و خطا میده که مقداری ثابت باید باشه. چطور این مشکل حل میشه؟
    z= (c^2)/(c!*4^c)*0.044

  4. فرنوش پارسی

    بله ولی این خطارو میده:
    Error 64: function called with non constant argument

    1. محمودی

      سلام
      این یعنی شما تابعی رو استفاده کردین که جلوش به جای اینکه عدد ثابت بذارین، رفتین یه متغیر گذاشتین.

  5. e.h

    e h:
    با سلام.
    امکان خطی سازی متغیر عدد صحیح ضربدر پیوسته هست؟
    z×y=m
    در رابطه z متغیر صحیح ۰،۱،۲یا ۳
    همچنین y متغیر مثبت پیوسته که باید برابر یا نصف یا ۱/۳ متغیر اصلی پیوسته m باشد
    و در اصل m متغیر اصلی که در محاسبات بدست میاد و باید تقسیم بر z بشه که y بدست بیاد جهت ساده سازی به صورت معادله فوق نوشته شده.
    ممنون میشم اگر راهکاری هست راهنمایی کنید.

      1. محمودی

        سلام
        چه اطلاعاتی نیاز دارین؟
        این ارور یعنی یه تابع مثل fact(x رو تو مدل استفاده کردین، در حالی که x متغیره. ولی تابع fact فقط برای مقادیر مشخص مثل parameter باید استفاده بشه.

  6. e.h

    میبخشین امکانش هست با جزییات بیشتر یا یک مثال در این مورد راهنمایی کنین؟
    امکان خطی سازی متغیر عدد صحیح ضربدر پیوسته هست؟
    z×y=m
    در رابطه z متغیر صحیح ۰،۱،۲یا ۳(این متغییر حاصل جمع مجموعه متغییر باینری که در یک معادله همزمان در این مدل حل میشه)
    همچنین y متغیر مثبت پیوسته که باید برابر یا نصف یا ۱/۳ متغیر اصلی پیوسته m باشد
    و در اصل m متغیر اصلی که در محاسبات بدست میاد(این هم مثل بالاست همزمان محاسبه میشه) و باید تقسیم بر z بشه که y بدست بیاد جهت ساده سازی به صورت معادله فوق نوشته شده.
    ممنون میشم اگر راهکاری هست راهنمایی کنید. من در مورد خطی سازی حاصل ضرب متغیر باینری در عدد پیوسته یه سایت بود استفاده کردم ولی در مورد عدد صحیح در پیوسته روش خاصی ندیدم.

    1. محمودی

      سلام
      وقتی به همون سوال ریپلای نمیکنین بحث گم میشه. الان چندتا سوالا بالا رو نگاه کنین. هیچ ربطی به هم ندارن. نمیشه اینجوری

  7. e.h

    محمودی می گوید :
    مرداد ۲۶, ۱۳۹۷ در ۲۲:۴۱
    سلام
    محاسبات قبلی یعنی از یه مدل دیگه خروجی گرفته شده و به عنوان ورودی به مدل جدید داده میشه؟ اگه اره که باید از suffix استفاده کنین. اگه نه که بریم ادامه ماجرا:
    برای اینکه تقسیم بر صفر نده، طرفین وسطین کنین و vsfp رو در vsfbush1 بکنین. برای مقدار صفر هم که گذاشتین برای متغیر صفر و یک کار بی معنی ای نیست آیا؟
    برای خطی کردنش دردسر دارین. شاید به صرفه نباشه خیلی. مثلا یکی از راه ها اینه که vsfp رو به مجموع سه متغیر صفر و یک تبدیل کنین (تو یه محدودیت جدا). بعد که طرفین وسطین انجام دادین حاصلضرب سه متغیر صفر و یک رو در متغیر مثبت باید خطی کنین که حدود ۱۰ تا محدودیت احتمالا به مدلتون اضافه میشه.

      1. e.h

        عذر خواهی میکنم من این سوال رو در دو قسمت( بخش خطاهای گمز و تلرانس متغیرهای INTEGER ) با دو شکل مختلف البته با یک مفهوم مطرح کرده بودم دلیل هم دیر شدن پاسخ بود و در این قسمت هم پاسخ که در بخش خطاها داده بودین گذاشته بودم من سوالم رو در اون بخش ادامه میدم به خاطر ایجاد سرگیجه ای که براتون اوردم باز هم ببخشید:)

  8. پیمان شهبازی

    سلام من در کدم میخوام در یک محدودیت یکی از متغیرها رو بزرگتر مساوی یک عدد خیلی کوچیک مثل ۱۰ به توان منفی ۱۶ قرار بدم ، اما در حل مسئله میبینم که اون رو صفر در نظر گرفته و فقط در صورتی صفر نمیشه که ۱۰ به توان منفی ۷ قرار بدم ، راهی برای این مشکل وجود داره؟ لطفا راهنمایی کنید خیلی ممنونم

    1. محمودی

      سلام
      تلرانس رو درست کردین؟ ضفرش کردین؟ اگه این میزان از تلرانس کمتر باشه، عمل نمیکنه.

  9. حسین زاده

    سلام و عرض ادب
    من روی یک مدل زمانبندی کار میکنم. برای زمان پایان بعضی از عملیات شناوری وجود داره. مثلا زمان پایان یک عملیات میتونه از a تا b را اختیار کنه بدون اینکه روی بهینه بودن جواب نهایی تاثیر بذاره. اما روی مقدار متغیرهای دیگه تاثیرگذاره. دستوری وجود داره که سالور حد پایین را برای اینجور متغیرها انتخاب کنه؟

    1. شما می توانید حد بالا و پایین برای متغییر هاتون تعریف کنید
      اما قطعا روی بهینه بودن جواب نهایی تاثیر می گذارد
      سوالتون رو واضح بپرسید

  10. حسین زاده

    فرض کنید در یک مسئله زمانبندی مقدار بهینه برای cmax یا makespan برابر ۱۰۰ بدست آمده. حل مسئله توسط Cplex نشان میدهد که زمان پایان یک عملیات مشخص می تواند مقادیر ۵۰ تا ۶۰ را اختیار کند بطوریکه با هر مقداری در این بازه مقدار بهینه تابع هدف همان ۱۰۰ بماند. سوال من اینه که آیا می توان شرایطی برای سالور تعریف کرد که در اینجور موارد همیشه مقدار کمتر را برای متغیرها انتخاب کند؟

    1. محمودی

      سلام
      یکی از مشکلاتی که کاربران با این جور مسائل دارن همینی هست که فرمودین.
      برای رفع این مشکل، معمولا میان یه محدودیت اضافه میکنن که اجبار کنه که مثلا زمان اتمام برابر با زمان شروع به اضافه دیوریشن هست. بسته به نوع مسئله کارای خلاقانه میشه انجام داد.

  11. عصمت

    سلام
    من یک مدل موجودی دارم که تعداد ارسال انباشته یک متغیر عدد صحیح می باشد که در گمز با integer variable تعریف کردم برای اینکه مقدار صفر را شامل نشود حد پایین یک برای متغیر تعریف کردم پس از حل با گمز مقدار ۵٫۰۷۳ را نمایش می دهد که صحیح نیست ممنون میشوم اگر راهنمایی بفرمایین.

    1. محمودی

      سلام
      سه option زیر رو به قبل از دستور solve اضافه کنین. توجه کنین intvarup برای نسخه های بالای ۲۴٫۷ کار میکنه. اگه مدل نشدنی بشه، یعنی مشکلی هست و باید رفع کنین. اگه نه که چه بهتره. کارتون درسته.

      option optcr=0,
      option optca=0
      option intvarup=0;
      
  12. عصمت

    ممنون از توضیحاتتون، دو آپشن اول که فرمودین در کد قرار داده بودم و تنها از آپشن سوم با توجه به گمز ۲۳٫۵ که دارم استفاده نشده. حالا با این وصف میشه راهنمایی بفرمایین؟

    1. محمودی

      نه به روز کنید نسخه رو قطعا.
      اگه نمیخواید اینکارو بکنین. برای هر متغیر اینتیجرتون. یه حد بالا مثلا ده هزار یا هر مقداری که مطمئن هستین هیچ متغیر عدد صحیحی تو مدلتون این مقدار رو نمیتونه بگیره برای تک تکشون در نظر بگیرین. مثلا x یه متغیر اینتیجر باشه.

      x.up=900;
      
  13. امین

    سلام.ببخشید می خوام یه متغیر پس از حل در صورتی که از یه مقدار کمتر بشه دوباره مسیله از اول شروع شه یعنی متغیر مقدار جدید به خودش بگیره.این امکان پذیره؟؟چون در گمز م نمیشه روی متغیر شرط نوشت.ممنون میشم کمکم کنید.

    1. محمودی

      سلام
      از چه مقداری کمتر بشه؟ این مقدار چی هست؟

      1. امین

        یه متغیر به نام ولتاژ باس که می خوام اگه در باس انتها از یک سطح کمتر شه، اونوقت ولتاژ در باس ابتدا یه پله افزایش پیدا کنه که همه ولتاژها در محدوده مشخص خودشون باشند.ولی مشکل اینه که ولتاژها متغیرند و‌پس از حل مشخص می شن.
        ممنون از شما

        1. اون ولتاژ اسلک رو متغییر تعریف کنید و اتوماتیک برای بالا آوردن ولتاژ انهتای شبکه خودش باید زیاد بشه و میشه

دیدگاهی دارید؟