تولید اعداد تصادفی در نرم افزار گمز gams

تولید اعداد تصادفی در گمز نسبت به سایر نرم افزارها آسان تر است. شما با در دست داشتن توزیع مربوطه، می توانید به آسانی عدد تصادفی مربوطه را تولید نمایید. کد زیر نحوه ی تعریف اعداد تصادفی در gams را نشان می دهد.


x(i)=uniform(a,b);
x(i)=normal(Mean,Sd);
x(i)=gamma(alpha,theta);
x(i)=F(df1,df2);
x(i)=beta(alpha,beta);
x(i)=binomial(N,p);

در کد بالا:
a,b حدود بالا و پایین توزیع یکنواخت
mean و sd به ترتیب میانگین و انحراف معیار توزیع نرمال
alph و theta مشخصه های توزیع گاما
df1 و df2 درجات آزادی در توزیع F
alpha و beta مشخصه های توزیع بتا
binominal توزیع دو جمله ای بوده و n و p مشخصه های آن می باشند.
سایر توزیع ها را در help نرم افزار می توانید مشاهده کنید. همچنین می توانید با ترکیب این توزیع ها توزیع دلخواه خود را با ترکیب این توزیع ها تولید نمایید.

یک نکته‌ی بسیار مهم:
برای تولید اعداد تصادفی در گمز، در واقع یک موتور تعریف شده است که هر بار اعداد مشخصی را تولید خواهد کرد که واقعا تصادفی نیستند. یعنی اگر شما مدل را چندبار run کنید، داده هایی که توسط توزیع هایی مانند uniform(a,b) برایتان تولید می کنند دقیقا با هم برابر هستند و با هر بار run کردن مدل این اعداد هیچگونه تغییری نمی کنند.
یعنی شما اگر کد زیر را هزار بار هم ران کنید، یک جواب مشخص غیر قابل تغییر به شما می دهد.

parameter a;
a=uniform(0,1);
display a;
*** a=0.172 always

برای رفع این مشکل، شما باید موتور گمز را مجددا راه اندازی نمایید و عدد تصادفی جدیدی تولید کنید. برای اینکار باید از دستور execseed استفاده کنید.
در کد که در زیر مشاهده می کنید، ما قبل از دستور uniform از دستور execseed استفاده کرده ایم. این کار باعث می شود که موتور تولیدی gams مجددا راه اندازی شود. شما به این کد کاری نداشته باشید. فقط این خط را در کد خود paste نمایید و مدل را ران کنید. لازم به ذکر است که عدد ۲۰۰۰۰ می تواند از صفر تا ۱۰ به توان ۹ تغییر کند. شما هر چه این عدد را بزرگتر در نظر بگیرید، اعداد تصادفی متنوع تری را برای شما تولید خواهد کرد.


set i /1*5/;
parameter x(i);
execseed = 20000*(frac(jnow));
x(i) = uniform(0,1);
display x;

ایمیل: Support@gamsbook.ir
شماره تماس: ۳۳۲۵-۴۰۵–۰۹۱۹

 

این مقاله برای شما مفید بود؟

مطالب مشابه

10 دیدگاه

  1. علیرضا روشنی

    سلام وقتتون بخیر
    یه سوال مهم داشتم ممنون میشم اگر راهنمایی بفرمایید.
    من با کد زیر یک عدد تصادفی پواسون درست کردم. که مشکلی نداشته و درسته.

    $funclibin stolib stodclib
    Functions randpoisson     /stolib.dPoisson/;
    
    Set i /i1*i3/;
    Set j /j1*j2 /;
    Parameter randx(i,j)    "distribution sample";
    
    randx(i,j)     = randpoisson(4);
    display randx;
    

    در مدلی که مد نظرم هست، نرخ توزیع پواسون (که در مثال بالا عدد ۴ هست) خودش یک متغییر تصادفی هست. حالا چه طور میشه مقدار یک variable رو جایگزین عدد ۴ در randpoisson کرد؟
    ممنون میشم اگر زودتر پاسخ بدید، چون مربوط به پایان نامم هست و فرصتم محدوده.
    ممنون از شما

    1. محمودی

      سلام
      دو نکته:
      اول اینکه، متغیر تو این تابعی که تعریف کردین نمیاد. اگه حتما باید متغیر باشه، باید فرمولش رو به صورت دستی بنویسین. یعنی مثلا لاندا به توان فلان و فلان.
      دوم اینکه، اینی که تعریف کردین منظورتون چیه ازش؟ حالا فرضا همون ۴ هم باشه. rand…..(4 چی رو به شما نشون میده؟ تعاریف رو دقت کنین.

  2. محمد

    سلام و عرض ادب
    سپاس از راهنمایی هاتون
    یه سوال داشتم آیا برای پارامتر دو یا سه بعدی (تحت دستور table) هم میشه عدد رندوم تعریف کرد؟
    چون با این الگو تعریفش میکنم جواب نمیده

  3. محمد

    سلام مجدد
    عرض به حضورتون که من یک دستوری نوشتم که برای زمان هست
    زمان چند مسیر (یعنی یک شبکه ای از مسیرهای مختلف هست که شامل مبدأها و مقاصد مختلف هست)
    t(i,j) یعنی پارامتر دو بعدی هست که به مبدا و مقصدم مربوط میشه
    خب طبیعتا در حال حاضر من تحت دستور table یک ماتریس دو بعدی براش تعریف کردم و دیتاش رو به صورت دستی وارد کردم
    در حالیکه حالا میخوام برای دیتاش یک بازه زمانی تعریف کنم که به صورت تصادفی از اون بازه دیتا بگیره
    تو تعاریفی که دیدم برای تولید عدد تصادفی همشون تحت دستور parameter بوده و تک بعدی بوده
    حالا برای دوبعدی و یا سه بعدی نمیدونم چطور میشه این عدد رو تولید کرد
    چون با همون الگو که دستور دادم جواب نداد
    ممنون از راهنمایی تون

    1. محمودی

      سلام
      برای بعدهای مختلف فرقی نمیکنه. شما همون فرمولی که برای تک بعدی هست. برای چند بعدی بنویسین.

      parameter t(i,j);
      t(i,j)=uniform(10,20);
      
  4. محمد

    متشکرم
    فقط ممنون میشم که بفرمایید برای اینکه بخواهیم عدد تصادفی مورد نظر عدد صحیح باشه باید چه دستوری رو بهش اضافه کنیم؟

    1. محمودی

      سلام
      یعنی مثلا نرمال یا یکنواخت تولید کنه بعدش عدد صحیح بشه؟ میتونین از ceil, floor یا round استفاده کنین. floor جزء صحیح رو به پایین میگیره. ceil رو به بالا و round هم رندش میکنه. مثلا x رو میخواین عدد صحیح باشه،

      x=round(uniform(.5,3.8)
      
  5. moon

    سلام و وقت بخیر؛
    ممکنه لطفا راهنمایی بفرمائید مدل بهینه سازی برنامه ریزی تصادفی (stochastic programming) رو چطور میشه تو گمز کد کرد؟
    من یه مدل mip برنامه ریزی تصادفی دارم که سعی کردم کدش کنم، جوابش هم اپتیمال میشه منتها خروجیارو که چک میکنم عددا منطقی نیست باتوجه به خود مسئله و فک میکنم تو روش کدنویسی برنامه ریزی تصادفی مشکل دارم.
    روش کدنویسیه من به سادگی به اینصورت بوده که برای تعداد سناریوها یه مجموعه تعریف کردم، فرض کنید:
    set
    S /1*3
    ;
    و برای احتمال وقوع هر سناریو هم یه پارامتر به اینصورت:
    parameter
    p(s) /1 0.3,2 0.35,3 0.35
    ;
    و در کل مدل S بعنوان یه مجموعه در متغیرها و پارامترهایی که توضون اثر داشته اعمال شده.
    اشتباه کردم نه؟

    1. محمودی

      سلام
      اگه درست پیاده کرده باشین نه اشتباه نیست. روش که درسته.
      فقط حل مسائل تصادفی روش های ویژه ای داره.
      اینا رو جستجو کنین تو مقالات. یا کتاب دکتر میرحسنی (برنامه ریزی تصادفی)
      Wait and see method
      here and now method
      EV method
      SAA method
      که اخری یه روش حل برای روش here and now هست.
      wait and see و EV روشهای راحت تری هستن به نسبت.

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