انواع حلقه در گمز | GAMS loops

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

حلقه Loop:

عمومی ترین حلقه در گمز loop است که در زیر ساختار کلی آن را مشاهده می کنید.


Loop( (sets),
 statement or statements to execute
);

در کل بالا، sets اندیس یا اندیس هایی هستند کهرطبق آن ما می خواهیم که حلقه امان عمل کند. و statements هم شامل گذاره ها یا عملیاتیست که در هر لوپ مایلیم محاسبه یا انجام گیرند.

چند نکته:

گذاره ها در دستور Loop می توانند بیشتر از یک عدد باشند.

گذاره ها میتوانند شامل مواردی از قبیل if, put و display  و کاربردی تر از همه solve هم باشند. یعنی توسط لوپ می توان یک دستور solve را چندین بار ران گرفت و هر سری نتایج را ذخیره کرد. این عمل در مدلهای دینامیک، تجلیل پوششی، عدم قطعیت و… بسیار کاربرد دارد.

درون یک لوپ می توان یک نرم افزار دیگر را اجرا یا فراخوانی کرد. به عنوان مثال میتوان یک داده را از روی اکسل خواند و یا توسط آن دستور داد که یک نرم افزار دیگر اجرا شود و نتیجه آن به گمز بازگردد.

مهم، هیچ equationی نباید درون دستور loop قرار گیرد.

در سایز های بالا ترجیحا از دستور display در حلقه ها خودداری کنید. چرا که این عمل موجب افزایش حجم فایل lst می شود و ممکن است مشکلاتی را در پی داشته باشد. البته در صورت وجود چنین مشکلاتی می توانید از این تاپیک استفاده کنید.

 

چند مثال:


* Example 1
set t / 1985*1990 /
parameter pop(t) / 1985 3456 /
growth(t) / 1985 25.3, 1986 27.3, 1987 26.2
1988 27.1, 1989 26.6, 1990 26.6 /;

loop(t, pop(t+1) = pop(t) + growth(t) ) ;

* example 2
Loop (i,
problemdata=savparam(i);
Solve mymodel using lp maximizing profit;
Data(i)=profit.l;
) ;

* example 3
* Note that k is a set, not a parameter
loop(index,
k(index)=yes;
solve lptest using lp minimizing lam;
);

* Example 4
put / ’Type one’ / ;
loop(i,
put / ’- Mode : ’ @۲۰ i.tl:1
/ ’- Date (mm/yy) : ’ @۲۰ i.tl:5 @19 i.tl:3 @19 ’ ’ @۲۲ ’/’
/ ’- Item Type : ’ @۱۵ i.tl:7 @15 ’ : ’
/
);
put / ’Type two’ / ;
loop(i,
put / @20 i.tl:1 @1 ’- Mode : ’
/ @۲۰ i.tl:5 @19 i.tl:3 @22 ’/’ @۱ ’- Date (mm/yy) : ’
/ @۱۵ i.tl:7 @1 ’- Item Type : ’
/
);

* example 5
loop(i$ ord(i)  gt  3,
if (x(i)  lt  y(i),
a=4;
);
);
* Example 6
set i/1*2/
parameter x/2/,z;
loop(i$x, z=3;);

در مثال آخر دقت کنید که شرط نوشته شده در دستور Loop متناظر با عبارت: حلقه را اعمال کن به شرطی که x مقداری مخالف صفر داشته باشد.

حلقه while:

این حلقه در دو حالت عمومی زیر نوشته می شود. که در آن عبارت logical condition یک شرط را نمایش می دهد. حلقه ی while تا وقتی اجرا می شود که شرط ارائه شده در قسمت logical condition رعایت شود.

---- first way
While (logical condition,
statements to be executed While condition is true;
);
---- second way
$Onend
While conditional do
statements ;
Endwhile;

فرق دو روش فوق بسیار واضح است. در روش اول از پرانتز و ویرگول استفاده می کنیم. در روش دوم از $onend و do و Endwhile استفاده می کنیم. چند مثال زیر را با دقت مرور کنید تا کلیات این دستور ملکه ذهنتان شود.


While(x lt 10,
x=x+0.01;
);
$Onend
While x lt 10 do
x=x+0.01;
Endwhile;

While(prod(I,q(i)), z=2;q(i)=q(i)-2);

while(converge = 0 and iter lt lim,
root=(maxroot+minroot)/2;
iter=iter+1;
function_value=a-b*root+c*sqr(root);
if(abs(function_value) lt tolerance,
converge=1;
else
if(sign(function_value1)=sign(function_value),
minroot=root;
function_value1=function_value;
else
maxroot=root;
function_value2=function_value;);
);
* display iter,lim,root,minroot,maxroot,
* function_value,function_value1,function_value2;
);

حلقه ی for:
این حلقه نیز به دو صورت زیر تعریف می شود.

* first
for (i = start to|downto end [by incr],
statements;
);
* second
$Onend
For (i = start to|downto end [by incr] ) do
 statements ;
endfor;

در کد بالا، start ابتدای بازه و end انتهای بازه و incr مقدار افزایش در هر گام حلقه بوده و همگی عدد می باشند (این اعداد می توانند منفی یا مثبت باشند) و همچنین i نباید یک set باشد. به عبارتی i یک پارامتر تعریف می شود. چند مثال زیر موضوع را روش می کند.

* Example 1
scalar i ;
scalar globmin ; globmin = inf ;
option bratio = 1 ;
for (i = 1 to 1000,
x.l(j) = uniform(0,1) ;
solve ml using nlp minimizing obj ;
if (obj.l le globmin,
globmin = obj.l ;
globinit(j) = x.l(j) ;
);) ;
* example 2
for(x=1 downto 12 by 2,
 data(i)=x;
 );
* Example 3
$Onend
for x=1 downto 12 by 2 do
 data(i)=x;
 endfor;

حلقه repeat:

برای حلقه ی while توضیح داده شد که statement تا زمانی اجرا می شود که شرط ارائه شده در logical condition نقض شود. در دستور repeat جای logical condition و statement عوض می شود. کد زیر را مشاهده کنید:



repeat ( statements to be executed;
 until logical condition is true );

به عبارتی repeat تا وقتی اجرا می شود که logical condition رعایت نشود. در صورتی که logical صحیح باشد، گمز از ادامه ی repeat صرفه نظر می کند.

چند مثال:


** Example 1
repeat (
a=uniform(2,10);
solve mymodel using minlp max z;
display a,z.l;
until (z.l<=5) ;);
** 2 Example
repeat(
  root=root+inc;
  function_value2= a-b*root+c*sqr(root);
  if((sign(function_value1) ne sign(function_value2)
    and abs(function_value1) gt 0
    and abs(function_value2) gt tolerance),
      maxroot=root;
      signswitch=1
  else
    if(abs(function_value2) gt tolerance,
      function_value1=function_value2;
      minroot=root;));
  until (signswitch gt 0 or root  gt maxroot)) ;;
** example 3
repeat(
v=v+1;
break$(v-1=3);
%innerLoop%;
until v>3;

 

نکته: یک شرط توقف برای while, for و repeat استفاده از آپشن زیر است که تعداد تکرارهای هر کدام از دستورات ذکر شده را به تعداد number محدود می کند.

 option forlim=number; 

توجه: در حلقه ها تعاریف نمی توانند قرار گیرند. مثلا درون یک حلقه نمی توان یک مجموعه را تعریف کرد. یا یک پارامتر را تعریف کرد. همچنین در یک حلقه نمیتوان یک equation.. نوشت. دو مثال زیر که کاملا اشتباه است گواه این مدعاست.


for (s = 1 to 5 by 1,
eq.. sum(i,x(i)) =g= 2 ;
);
for (s=1 to 5 by 1,
scalar y ; y = 5 ;
);

توجه:! حلقه ها با سایز بالا در گمز سرعت پایینی نسبت به سایر زبان های برنامه نویسی دارند. از اینرو همیشه به یاد داشته باشید که در صورتی حلقه ی تعریف شده ی شما زمانبر است، از شرط ها، if و سایر دستورات کمکی استفاده کنید که سرعت حلقه بالاتر رود. در صورتی که این عمل نیز اثر نکرد از سایر زبان ها و نرم افزار ها مانند اکسل و متلب برای محاسبات عادی استفاده نموده و خروجی آنها را در گمز وارد کنید.

در کد تا جایی که برای شما امکان دارد به جای حلقه ها از عبارات معادل آنها استفاده کنید. به عنوان مثال در کد زیر رویه ی دومی که برای پارامتر u تعریف شده است سرعت عمل بیشتری نسبت به رویه اول دارد.


set I / 1 * 100000 /;
parameter u(I);
* bad!
loop { I,
u(I) = uniform(0,2);
};
* good
u(I) = uniform(0,2);

]

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

102 دیدگاه

  1. محمد جعفری صور

    با سلام و وقت بخیر
    بنده روی مدل ahp-dea کار میکنم . متاسفانه تو برنامه نویسی توی گمز دچار مشکل شدم
    باید داده های ۹ تا واحد رو بگیریم ( ۵ ورودی و ۳ تا خروجی) ، بعد هر یک از واحدها رو دو به دو باهم مقایسه کنیم . این مقایسه شامل حل چهار تا مدل dea-ccr ساده است . و بعد اعداد به دست آمده از این چهار مدل باهم جمع و تقسیم میشن و جوابهای نهایی یه ماتریس ۹*۹ تشکیل میده .
    مشکل بنده یکی نوشتن حلقه تو در تو هست . که نمیدونم با loopبنویسم یا for !!!
    یکی هم اینکه چطوری نتایج رو توی ماترس یا جدول ذخیره کنم .
    ممنون میشم از دوستان کسی راهنمایی کنه .

    1. محمودی

      سلام
      با loop بنویسین. من یه نمونه براتون میذارم اینجا.

      loop(jj,
      xx(jj)=x(i,jj);
      
      solve mymodel using lp maximizing w;
      wFinal(jj)=w.l;
      );
      

      که wfinal کارایی برای هر واحده اینجا. تو مسئله شما هم لوپ باید دو تا اندیس داشته باشه (یا دو تا لوپ تو در تو)

  2. کاظم

    با سلام و وقت بخیر
    بنده روی یک پروژه بهینه سازی با گمز کار میکنم حال در انتها یک دستور لوپ میبایست بنویسم که به مشکل برخوردم،
    در داخل برنامه من یک Scalar دارم که مقدار اولیه آن به صورت دستی ۸٫۹ داده ام حال این مقدار را باید با گام ۰٫۱ افزایش بدهم تا ۱۶٫۴ و در هر افزایش گام میبایست بهینه سازی بنده مجدد انجام شده و خروجی ها رو را برای من سیو کند تا نهایت بتوانم کمترین مقدار را جدا کنم چطور باید بنویسم.
    ممنون میشوم راهنمایی بفرمایید.
    با تشکر

    1. محمودی

      سلام
      یه مثال براتون میذارم.

      sets t/1*10/;
      
      parameter TAWA0(t)
      /1        573E+6
      2        584.05E+6
      3        587.1E+6
      4        596.15E+6
      5        605.2E+6
      6        608.25E+6
      7        618.3E+6
      8        622.35E+6
      9        629.4E+6
      10        634.45E+6
      /
      ;
      
      parameter nlprofFinal(t);
      
      
      loop(t,
      TAWA=TAWA0(t);
      
      solve pmp using nlp maximizing nlprof;
      
      nlprofFinal(t)=nlprof.l;
      
      display nlprofFinal
      
      
  3. جوانه

    سلام وقتتون بخیر
    این جدول رو چطور در گمز بنویسم ( k = انواع بارگیر) (d=فاصله به کیلومتر) و اعداد جدول هم هزینه حمل یک تن بار در یک کیلومتر فاصله

    d<100	200<=d<=100	500<d<200 500<=d
    K1	8100	5200	3000	1900
    K2	6400	4500	3000	1900
    K3	4300	3400	2300	1300
    K4	2600	1800	1200	775
    K5	2400	1600	1100	660
    K6	2300	1600	1100	660
    K7   	1800	 1500	900	700
    
    1. جوانه

      فاصله بین مبدا و مقصد رو هم بر اساس کیلومتر نوشتم حالا هزینه جابجایی برای فواصل مختلف فرق میکنه مثلا باارگیر شماره ۱ برای فاصله کمتر از ۱۰۰ یه هزینه برای فاصله ۱۰۰-۲۰۰کیلومتر یه هزینه (هزینه حمل یک تن بار در یک کیلومتر فاصله) و …. دارهو سایر بارگیر ها هم همینطور

    2. محمودی

      سلام
      این جدول مقداری بحث برانگیز هست. میتونین یه اندیس دیگه به اسم i تعریف کنین که چهار عضو i1*i4 داشته باشه. بعد ازش تو جدول استفاده کنین. تو جاهای مختلف کد از این اندیس میتونین استفاده کنین.

  4. جوانه

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

    1. محمودی

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

  5. علی

    با عرض سلام
    من یه مسئله دارم که میخوام به ازای چندتا TABLE مختلف حلش کنم و بعد نتایج شون رو مقایسه کنم. حالا با توجه به اینکه داده های این TABLE ها جز متغیر های EQUATION ها هستن و اینکه EQUATION ها هم نمی تونن داخل حلقه ها قرار بگیرن آیا روشی وجود داره که بشه این مسئله رو به صورت تکراری داخل حلقه(به ازای هر TABLE) حل کرد یا اینکه باید به ازای هر TABLE تمام معادلات رو دوباره بنویسم و جداگانه SOLVE بگیرم؟

    1. محمودی

      سلام
      میتونین از دستور loop استفاده کنین به طوری که دستور solve تو لوپ مورد نظر باشه. فقط توجه کنین که شما توی لوپ نمیتونین تعریفی انجام بدین (مثلا یک پارامتر رو تعریف کنین). و اینکه حواستون باشه که هر بار که لوپ جلو میره نتایج هم توسط یه پارامتر ذخیره کنین.
      حتی میتونین چندین دستور solve تعریف کنین. ولی لوپ همیشه به صرفه تره.

  6. moslem

    سلام میشه بگین داخل یک حلقه چجوری میشه پارامتر ها رو ذخیره کرد؟

    1. moslem

      ببخشید منظورم این بود که چجوری میشه نتایج رو تو یک پارامتر داخل حلقه ذخیره کرد ، اگه واستون مقدور هست یک مثال بزنید.

    2. محمودی

      مثال زیر بهتون کمک میکنه:
      [css]
      loop(jj,
      xx(k,i)=x(jj,k,i);
      yy(k,r)=y(jj,k,r);
      zz(k,h)=z(jj,k,h);
      solve mymodel using nlp maximizing goalstar;
      eff(jj)=goalstar.l;

      lambdaFinal(k,jj,j)=lambda.l(k,j);
      );
      display eff,lambdaFinal;
      [/css[

  7. rezamohamad

    salam mn yeseri dade az expert choice daram bahayd to dea vared konam
    chetori bayad inharo vared konam
    kole ravaeshoAHP-DEA hast 3 ta meyar dram va 6 ta gozine va 4 ta dmu

  8. N.R

    سلام پیشاپیش ممنون که برأی پاسخم وقت میذارین. یه مدل ریاضی رودارم کدمیکنم که أفق غلطان یاrolling horizonهست وبرای هرهفته بایدتکرارشود سوال اولم اینه که مدل نوشتن حلقش چطوریه؟ و اگر درمحدودیتی درقسمت سور عمومی یه عبارت مثلا Ri=1 باشه کد چطوری میشه؟

    1. محمودی

      سلام
      خواهش میکنم. لطفا مسئله رو واضح تر بیان کنین در خدمت هستم.

  9. سیاوش

    سلام
    با تشکر از مطالب آموزنده شما. من چند تا سوال داشتم که ممنونتون میشم اگر فرصت دارید پاسخ بدید
    من یک نوع مسئله TSP رو کد کردم و حالا احتیاج دارم که این مسئله رو با یک سری شروط که منجر به تغییر مجموعه رئوس باقیمانده و همچنین نقطه شروع می شه حل کنم. روش کارم اینطور بوده که اول کد مسئله رو برای یک بار حل نوشتم و بعد قسمت Solve رو ازش برداشتم و یک لوپ به تعداد رئوس موجود براش ایجاد کردم که در صورتی که یک شرط خاص برقرار باشد باید مبدأ رو عوض کنه و مبدأ قبلی رو از مجموعه رئوس باقیمانده حذف کند و در صورتی که شرط برقرار نباشد یک رأس بخصوص را به صورت موقت حذف نماید تا در نهایت یا رأسی را بیابد که شرط برای آن برقرار شود یا دیگر رأسی غیر از مقصد نهایی باقی نماند. اگر رأسی پیدا شود رأس هایی که به صورت موقت حذف شده اند برای تکرار بعدی به الگوریتم بایستی بازگردند.
    ۱٫ آیا کاری کلیات منطق کار صحیح است؟ یعنی آیا می توان در یک لوپ به صورت مداوم مجموعه رئوس را تغییر داد و مسئله را حل کرد و آیا پارامترهایی که وابسته به این رئوس هستند نیز تغییر می کنند؟ مثلا اگر رأس iام از مسئله حذف شده باشد آیا بردار زمان خدمت دهی برورز می شود؟ یا باید تمام پارامترها را هم بروز کنیم؟
    ۲٫ چطور می توان به صورت موقت یک رأس را حذف نمود؟ یعنی در یه جاهایی رئوسی در یک مجموعه قرار بگیرند و در جایی میان الگوریتم با دستوری این مجموعه را تهی نمود.
    ۳٫ برای یک حالت از مسئله کد من جواب های زیر را داده است: همانطور که می بینید تکرار اول جواب منطقی است و شروط TSP برقرار است (حذف تور و یک بار وارد و خارج شده از هر رأس) (عرض کردم حالت خاصی از TSP هست این مسئله و ضرورتی به بازدید تمام رئوس نیست) ولی در تکرار های بعد رسما مسئله جواب غلط داده…. به نظر شما مشکل از کجاست؟
    جواب تکرار اول:
    ۳ ۴ ۵ ۷

    ۱ ۱٫۰۰۰
    ۳ ۱٫۰۰۰
    ۴ ۱٫۰۰۰
    ۵ ۱٫۰۰۰
    جواب تکرار دوم
    ۱ ۲ ۴ ۵ ۶ ۷

    ۱ ۱٫۰۰۰ ۱٫۰۰۰
    ۲ ۱٫۰۰۰
    ۴ ۱٫۰۰۰
    ۵ ۱٫۰۰۰
    ۶ ۱٫۰۰۰

    جواب تکرار سوم
    ۱ ۲ ۷

    ۲ ۱٫۰۰۰ ۱٫۰۰۰
    ۴ ۱٫۰۰۰
    جواب تکرار چهارم
    ۳ ۷

    ۲ ۱٫۰۰۰
    ۳ ۱٫۰۰۰
    ۷ ۱٫۰۰۰

    1. محمودی

      سلام
      مفهومی که دارین پیاده سازی میکنین مقداری پیچیده هست و چون من خارج از گود هستم نمیتونم درباره ش به قطع صحبت کنم. و یه جورایی به خلاقیت شما بستگی داره. من احساس میکنم که شما به چند مورد نیاز دارین که بتونین شروط رو بنویسین.
      اول اینکه، وقی میخواین یه شرط بنویسین که یه رأس حذف بشه، میتونین لوپ رو که نوشتین، یه پارامتر مثل kk که قبلا تعریفش کردین و مقداری به خودش نگرفته رو تحت لوپ بهش مقدار بدین، مثلا وقتی طبق شرایط مسئله این kk عدد ۳ رو گرفت، یعنی رأس ۳ باید حذف بشه، این پارامتر باید تو مدل به عنوان شرط اضافه بشه. مثلا تو یه محدودیت که داریم sum(xij=1 اونجا شرط می نویسیم ord(i) <>۳ یعنی برابر ۳ نباشه. (این یه فرضه که عرض کردم و هدفم اینه که متوجه بشین که کلیات کار چگونه هست و البته چون مسئله tsp پیچیدگی خاص خودش رو داره، باید بیشتر روش فکر کنین و ممکنه زمانبر باشه).
      اینکه مسئله شما جواب غلط میده، مشکل از خود کد نویسی هست. و باید محدودیت زیرتور رو به خوبی پیاده سازی کنین. محدودیت های زیر تور زیادی هستن که تو مقالات مورد بحث قرار گرفتن. ببینین کدومش براتون ساده تره. و به خاطر داشته باشین که همیشه راه بهتر و محدودیت بهتری هست که شما باهاش راحت تر باشین.
      اینکه میخواین مبدأ رو عوض کنین، راههای زیادی میتونین داشته باشین، یکیش اینه که مثلا اون متغیر مربوط بهش رو فیکس کنین با ویژگی .fx ، یه راه دیگه اش اینه که مثل همون kk رفتار کنین و یه پرارامتر دیگه تعریف کنین براش.
      برای سایر سوالات همه چی بستگی به مسئله شما داره. و معمولا نیازی نیست دوباره تعریف بشن پارامترها، با همین شرط ها و پارامترهای قبلی که تعریف کردین میتونین کار رو ببرین جلو.
      این که این مسائل رو کلی عرض کردم خدمتتون دلیلش اینه که بنده خارج گود هستم و دقیق تمیتونم راهنمایی کنم. ایشالا که موفق میشین.

  10. N.R

    سلام.میخوام یهloop بنویسم که برای هرهفته k تکراربشه و تعدادی قطعه i براشون سه محدودیت اعمال بشه حل کنه بعد میخوام نتایج این تخصیص با.fx ثابت کنم ممنون که راهنمایی میکنید.

  11. وحید

    سلام خسته نباشید میخوام سه عدد تصادفی بین صفر ویک تولید کنم که جمع شون برابر یک بشه لطفا کمک کنید

    1. محمودی

      سلام
      میتونین دو عدد تصادفی بین صفر و یک تولید کنین. و عدد سوم رو با محاسبات به دست بیارین. x,y رو تولید کنین. و z=1-x-y

  12. مهران

    سلام به همه دوستان.من حلقه لووپ نوشتم برای تحلیل حساسیت.حلقه لووپ رو به ازای مقادیر مختلف به دست آوردم.ولی وقتی او مقادیرو دستی وارد میکنم جوابش با حلقه لوپ فرق میکنه.لووپ داره اشتباه به من جواب میده.کسی میتوونه تووی این زمینه کمکم کنه خیلی گیر کردم.اگر مشکلی نیست به این شماره تلگرام کننین ممنون میشم
    ۰۹۳۰۷۴۰۳۸۶۸

    1. محمودی

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

      loop(i,
      x(i)=ord(i)/10;
      solve .....
      );
      

      در حلقه بالا ما میخوایم که فقط xi عدد بگیره. مثلا x1=1/10 و تو مرحله بعدی x2=2/10 و x1 حذف بشه. ولی نمیشه! پس باید بعد از دستور solve مجددا بنویسیم x1=0.
      ممکنه مشکلات دیگه ای هم باشه که اگه بیشتر توضیح بدین در خدمت هستیم.

  13. امین

    سلام من ی کد تو گمس نوشتم که کاراییی ۱۲dmu رو بررسی میکنه ولی موقع گرفتن خروجی فقط کاراییی ۱dmu رو نشون میده
    میخوام با استفاده از دستور loop کدی رو بهش اضافه کنم که کارایی هر ۱۲ dmu رو همزمان نشون بده
    [cs]]
    Sets
    i “Inputs” /i1 “Doctors”,i2 “Nurses”/
    r “Outputs” /o1 “Outpatients”,o2 “Inpatients”/
    j “Units” /DMU01*DMU12/;

    Parameters
    * Let DMU04 be under evaluation
    xo(i) “Inputs of under evaluation DMU”
    /i1 20
    i2 151/

    yo(r) “Outputs of under evaluation DMU”/o1 100
    o2 90 /;

    Table x(i,j)
    DMU01 DMU02 DMU03 DMU04 DMU05 DMU06 DMU07 DMU08 DMU09 DMU10 DMU11 DMU12
    i1 20 19 25 27 22 55 33 31 30 50 53 38
    i2 151 131 160 168 158 255 235 206 244 268 306 284;
    Table y(r,j)
    DMU01 DMU02 DMU03 DMU04 DMU05 DMU06 DMU07 DMU08 DMU09 DMU10 DMU11 DMU12
    o1 100 150 160 180 94 230 220 152 190 250 260 250
    o2 90 50 55 72 66 90 88 80 100 100 147 120;

    Variables
    v(i) “Input weights”
    u(r) “Output weights”
    z “Efficiency”;
    Positive Variables
    v
    u;
    Equations
    Objective
    Const1
    Const2(j);
    Objective.. z=e=Sum(r,yo(r)*u(r));
    Const1.. Sum(i,xo(i)*v(i))=e=1;
    Const2(j).. Sum(r,y(r,j)*u(r))-Sum(i,x(i,j)*v(i))=l=0;

    Model MultiplierCCR_Model /All/;

    Solve MultiplierCCR_Model Using LP Maximizing z;
    [/css]
    میدونم که باید alias رو اضافه کنم و مقدار پارامتر ها رو حذف کنم ولی نوشتن خود loop رو نمیتونم انجام بدم
    مرسی

    1. محمودی

      سلام
      شما باید اول jj رو به j آلیاس کنین.
      بعد به صورت زیر عمل کنین.

      Loop(jj,
      
      yo(r)=y(j,r);
      xo(i)=x(j,i);
      
      Solve MultiplierCCR_Model Using LP Maximizing z;
      zFinal(jj)=z.l;
      );
      
  14. با سلام.
    میخوام کد دستور Znm ک متغیر باینری هستش بنویسم، در واقع m و n نام گذاری دو سر خط.
    چطوری میتوانم در حلقه بیان کنم که به ازای z که از گره n به گره m میرود نتیجه صفر شود، ولی اگر شبکه را طوری تعریف کنیم که از گره m ب گره n نتیجه یک باشد؟!
    znm: Binary variable which is equal to 1 if m is the parent node of n
    ممنون میشم راهنمایی کنید. و برای ایمیلe.kh2731@gmail.comهم ارسال کنید.با سپاس

    1. محمودی

      سلام
      منظورتون اینه که وقتی znm یک باشه، اونوقت zmn باید برابر صفر باشه، و اگر اولی برابر صفر باشه، دومی باید برابر یک باشه؟
      این سوالو اول جواب بدین در خدمتتون هستم.

    1. محمودی

      این توضیحات در صورتی میتونه کمک کنه که همش رو کامل بنویسین. نه ifی نوشتین، نه اینکه نوشتین سیگما رو چیه و…

  15. davood

    سلام ، یه سوال داشتم.
    میخام مسئله ای رو حل کنم که سه تا ست داره:i,j,k که i مشتریان و k وسایل نقلیه هستن . مسئله رو میخام یک بار برای ۳ مشتری و ۴ وسیله یکبار برای ۴ مشتری و ۴ وسیله و یکبار برای ۳مشتری و ۳ وسیله و میخام این تغییرات برای j نیز باشه ؛مظورم اینه تعداد ست ها میخام تغییر بدم چطور باید اینکارو انجام بدم.

    1. محمودی

      سلام
      باید دستی تغییر بدین.
      اگه I,j شبیه به هم هستن. از alias استفاده کنین.

  16. نیلوفر

    سلام
    خوب هستین؟
    اگر یک تابع sum رو بخوام تعریف کنم که برای مثال از n=1 شروع میشه و تا یک متغیر صحیح مثل s میره چطور باید تعریف بشه؟ وقتی با متغیر صفر و یک تعریف می کنم و در محدودیت ها میارم یک محدودیت s>n لحاظ می کنه.

    1. محمودی

      سلام
      حد بالای متغیر مقداری فرمول نویسی میخواد. تو کامنتها قبلا جواب دادم. پیداش کردم بهتون reply میکنم. ولی به عنوان یه راه دیگه میتونین از تابع ifthen هم استفاده کنین.

  17. نیلوفر

    سلام
    خوب هستید؟
    میشه راهنمایی کنید وقتی حد بالای یک سیگما متغیر هست چطور باید اون رو مدل کرد که گمز ارور نده؟

  18. علی

    با سلام و خسته نباشید
    میشه راهنمایی بفرمایید کد دستور ریاضی زیر که در محدودیت های یک مساله می باشد در گمز به چه شکلی هستش
    min< x < max
    یا
    x=0
    به عبارتی میخوام اگه مقدار x مابین min و max قرار نگیرد برابر با صفر شود

    1. محمودی

      سلام
      فرض میکنم که max,min دو عدد کران هستن که مقدارشون رو میدونیم.
      کافیه یه متغیر صفر و یک به نام y تعریف کنین. که در معادله به شکل زیر اثر داده بشه. این برا وقتی هست که اون علامت مربوط به محدودیت شامل مساوی هم باشه.

      min*y<x<max*y
      
  19. پیمان

    سلام
    من یک کد نوشتم که در اون با استفاده از دستور لوپ در هر تکرار یک سری مقادیر محاسبه میشه و دوباره از همون مقادیر برای ادامه حل استفاده میشه ، می خواستم بدونم چطور میشه کاری کنم که اگر در یکی از تکرار ها ، مقادیر تکرار دیگه ای عینا بدست اومد گمز متوجه بشه و دستور دیگه ای رو انجام بده؟
    فرض کنید در تکرار دوم جوابها به صورت زیر بوده:
    Y0=1
    Y1=1
    Y2=0
    Y3=1
    حالا عینا همین مقادیر در تکرار هفتم بدست اومده:
    Y0=1
    Y1=1
    Y2=0
    Y3=1

    1. محمودی

      سلام
      فرضا Y شما یه اندیس داره به نام i یعنی به شکل y(i تعریف شده باشه. و اندیس مربوط به loop برابر j باشه. خب. میتونین یه پارامتر به نام yy(j,i تعریف کنین. بعد تو دستور loop یه دستور شرطی if تعریف کنین. و بگین که در صورتی که yy(j,i)=yy(j-1,i) اونوقت فلان عبارت رو برای من display کن. در غیر اینصورت به عبارت دیگه رو نشون بده.

  20. hashemi

    سلام
    من یک پارامتر دارم که قبل از ورود به equations نیاز به محاسبه اش دارم منتهی این پارامتر دو اندیسی هست و باید به صورت یک table ایجاد بشه آیا اصلا امکان این هست از حلقه loop استفاده بشه ؟؟

    table sc(I,q) slop for cost
    
    loop((i,q) $((nt(i,q)-ct(i,q)) ne 0),
           sc(i,q)=(cc(i,q)-nc(i,q))/(nt(i,q)-ct(i,q)););
    
    display sc;
    

    من به این صورت نوشتم اما با خطای۴۶۳ مواجه می شم

    1. محمودی

      سلام
      شما نباید به صورت table تعریف کنین. باید sc رو به صورت parameter تعریف کنین.

  21. نیکو

    با عرض سلام و وقت بخیر
    امکان داره لطف کنید ببینید اشکال این کد چیه که خطای ۴۳۹ رو میده

    /۵*set i /1
    ;(parameter x(i), d(i
    ;(( execseed = 20000*(frac(jnow
     ;(x(i) = uniform(0,1
               , for(i=1 to 5
              ,  if(x(i)&gt;0.5
                  ; d(i)=1
               ,  elseif x(i)&lt;=0
                  ; d(i)=0
    
                  );
                 );
    
    1. محمودی

      سلام
      تو for اندیس نداریم، باید با loop بنویسین:

      set i/1*5/;
      parameter x(i), d(i)          ;
       execseed = 20000*(frac(jnow));
      x(i) = uniform(0,1);
       loop(i,
       if(x(i)>0.5,
       d(i)=1  ;
       elseif x(i)<=0,
       d(i)=0;
      
      ););
      
      
  22. کمیل

    سلام…
    تو دستور زیر که من i , j رو قبلا alias کردم و i و j برابر می شوند
    (f(i,j) =e= (v(i)-v(j))/z(i,j
    معادله مربوط به جریان است و صفر می شه و گمز ارور صفر شدن عبارت رو میده
    می خوام بگم در زمان هایی که iو j مخالفند فرمول رو اجرا کنه.. چطوره؟
    سوال دوم .. قبل عبارت بالا هم میخوام بگم وقتی از i به j خطی وجود داره ( که z وجود داشته باشه) فرمول رو اجرا کنه
    جدول z قبلا معرفی شده
    با تشکر

  23. سهراب

    با سلام و خسته نباشید
    اگر امکان داشته باشد لطفا در نوشتن کد مسئله زیر به بنده کمک کنید
    مسئله بصورت زیر است:
    زمان بصورت مجموعه تعریف شده است: / set t /1*10
    همچنین u(عدد باینری) یک متغیر است.
    در ساعات ۴تا ۸ یا ۵تا ۹ (بطور کلی، ۵ ساعت بطور پیوسته) موقعی که u برابر ۱ است، خروجی به ترتیب اعداد ۱، ۲، ۳، ۴ و ۵ را تولید کند و در بقیه ساعات، خروجی به ازای هر ساعت برابر صفر باشد.
    بطور مثال موقعی که Ut=0 0 0 1 1 1 1 1 0 0، خروجی برابر P= 0 0 0 1 2 3 4 5 0 0 باشد.
    با تشکر

    1. محمودی

      سلام
      سوال ناقص مطرح شده. ولی از فرمولایی نظیر معادله زیر میتونین استفاده کنین که کار رو جلو ببرین:

      eq1(t)..  p(t)=l=p(t+1)+(1-u)*M;
      eq2(t).. p(t)=l=u*M;
      

      این مفهوم رو میرسونه که هر جا U صفر هست، p هم صفره. و ترتیب ۱ تا ۵ رو هم نشون میده.

      1. سهراب

        با تشکر از راهنماییتان
        پارامترها و عدد m را به چه صورتی تعریف کنم؟
        همین دو معادله eq1 و eq2 کافی است؟
        با تشکر از شما

        1. سهراب

          همین طور در قسمت متغیر باینری (u)، قسمت زیر را به چه صورتی بنویسم؟
          Ut=0 0 0 1 1 1 1 1 0 0
          اگر امکان داشته باشد لطفا راهنمایی بفرمایید
          با تشکر از شما

        2. محمودی

          وقتی میگین متغیره، یعنی نمیدونین مقدارش چنده دیگه. مسئله به دست میاره.

        3. محمودی

          m یه عدد بزرگه در حدی که کافی باشه! یعنی نه خیلی بزرگ، نه اونقد کوچیک که مسئله نشدنی بشه.
          این دو تا با این اطلاعات تقریبا کافی هست. شما باید هر چی فرض دارین حول و حوش این دو محدودیت به کار ببرین و هر بار محدودیت ها را بهترشون کنین.

  24. فرهاد

    با سلام:
    چطوری میشه در گمز ضرب یک متغیر گسسته در یک متغیر باینری رو انجام داد؟
    با تشکر

    1. محمودی

      سلام
      خطی سازی میخواید؟ بدون خطی سازی که میشه. برای خطی سازی هم روش زیر خوبه. مثلا x باینری و y عدد صحیح باشه و z هم یه عدد صحیح جدید.

      integer variable z;
      z=g=y-(1-x)*M;
      z=l=y;
      z=l=x*M
      

      روش های دیگه ای هم هست. ولی همین کارتون رو راه میندازه. m عدد بزرگه.

      1. فرهاد

        با سلام
        در حقیقت من می خواهم حلقه ای بنویسم که ضرب یک عدد باینری را در یک عدد گسسته در پنج حالت انجام دهد و خروجی آن نشان داده شود.سپس شمارنده یک واحد اضافه گردد و دوباره عمل ضرب انجام گردد.. تا موقعی که هر ۵ حالت تمام شود و تمام خروجی ۵ حالت نشان داده شود. بطور مثال
        حالت اول u1*r1
        حالت دوم u1*r2
        و… تا حالت پنجم
        خروجی برنامه، حاصلضرب تمام حالتها را نشان دهد.
        تمام مقادیر u و r هم مشخص است.
        با تشکر از سایت خوبتان

        1. فرهاد

          با سلام
          مقادیر u1 تا u5 مشخص هستند. u2 ، u1 و u3 برابر ۱ و u4 و u5 برابر صفر هستند.
          با تشکر از سایت خوبتان

        2. محمودی

          سلام
          من یک برنامه کلی براتون مینویسم. ازش استفاده کنین.

          sets i/1*5/
          alias(i,j);
          parameter u(i),r(i),x(i,j);
          x(i,j)=u(i)*r(j);
          

          اینجا شما باید u,r رو عدد دهی کنین. و x هم که طبق فرمول محاسبه میشه.

  25. سهراب

    با سلام و خسته نباشید
    اگر امکان داشته باشد در نوشتن کد گمز مسئله زیر به بنده کمک کنید
    مسئله ای بصورت زیر تعریف شده است
    زمان یا t بصورت مجموعه و ۱۰ ساعت در نظر گرفته شده است / set t /1*10
    u (عدد باینری) یک متغیراست
    سوال بدین صورت است. موقعی که u در ساعات ۵ تا ۹ یا ۴ تا ۸ (۵ساعت بطور پیوسته) برابر ۱ است، خروجی اعداد ۲، ۴، ۶، ۸ و ۱۰ را به ترتیب تولید کند و در بقیه ساعات خروجی برابر صفر باشد. یعنی هر موقع u در ۵ ساعت بطور پیوسته برابر ۱ باشد، خروجی به ترتیب اعداد ۲، ۴، ۶، ۸ و ۱۰ را ترتیب تولید کند و در بقیه ساعات صفر باشد.
    تابع هدف هر چیزی می تواند باشد. چون خروجی فقط یک جواب دارد و اعداد بالا در ساعات متناظر را تولید می کند
    اگر امکان داشته باشد لطفا راهنمایی بفرمایید.
    با تشکر از زحمات شما

    1. محمودی

      سلام
      وقت بخیر
      شما لطفا این سوال بنده رو اول جواب بدید در خدمتتون هستیم.
      اینکه اگر u در چهار ساعت از اون ۵ ساعت برابر با ۱ بشه ولی در ساعت آخر یا ساعت وسطش یک نشه، نتیجه چی میشه؟

      1. سهراب

        با سلام خدمت شما
        خیلی ممنونم از پاسخ گویی شما
        کلن فرض بر این است که ۵ ساعت بطور پیوسته برابر یک باشد و در ساعت اول خروجی عدد ۲، در ساعت دوم خروجی عدد ۴ و … در ساعت پنجم عدد ۱۰ را تولید کند. حالا ساعت ۴تا ۸ یا ۵ تا ۹ فرقی ندارد. یعنی ۵ساعت u بطور پیوسته برابر ۱ باشد و بین این ساعت u نمی تواند برابر صفر باشد.
        با تشکر از شما

        1. محمودی

          سلام
          اطلاعاتی که دادین خیلی مناسب نبود. ولی برنامه زیر این کارو میکنه. اگه تغییراتی خواستین بدین میتونین از همین استفاده بکنین تا حدی.

          
          sets t/1*10/;
          integer variable x(t);
          binary variable u(t);
          variable z;
          
          equations
          eq1,eq2,eq3,eq4,eq5;
          eq1.. u('4')+u('9')=e=1;
          eq2(t)$(ord(t) >=5 and ord(t) <=8).. u(t)=e=1;
          eq3(t).. 2*u(t)=l=x(t);
          eq4(t).. x(t+1)=g=(2+x(t))*u(t+1);
          eq5(t)..   z=g=x(t);
          
          model mymodel /all/;
          option optcr=0,minlp=lindo;
          solve mymodel using minlp minimizing z;
          
          display z.l,x.l,u.l;
          
          
        2. سهراب

          با سلام
          خیلی خیلی سپاسگزارم از جنابعالی. اگر امکان داشته باشد لطفا به این سوال هم جواب بدید.
          اگر خروجی بجای اعداد ۲، ۴، ۶، ۸ و ۱۰ ، به ترتیب اعداد ۱۰، ۱۳، ۱۵، ۱۶ و ۱۷ را تولید کند نامساویها چگونه تغییر می کنند؟
          منظورم اینست که خروجی از یک رابطه خاصی تبعیت نکند.
          خیلی ممنونم از شما

        3. محمودی

          سلام
          اینو دیگه باید تک تک براش محدودیت بنویسین. اینجا ما نوشتیم به ازای هر t بیا این کار رو انجام بده. ولی با شرایط فوق دیگه قضیه فرق میکنه. باید عبارتی مثل زیر باشه:

          x('7')=g=(1+x('6'))*u('7')
          

          شما باید تک تک برای زمان های مختلف محدودیت بنویسین.

  26. leila

    سلام و وقت به خیر..سوالی داشتم ممنون میشم پاسخ بدین..میخوام یه محدودیتی تعریف کنم به این مفهوم که حاصل sum یه عبارت شامل متغیرهای باینری که تابع t هست رو تو بازه ای با حد بالا و پایین بهم بده ( t (بازه زمانی ۱۵ دقیقه ای که از ۱ تا ۹۶ هست) به ازای t بزرگتر از k و کوچکتر ازK+7 … حالا خود K هم یه زیر مجموعه کوچتر از t هست مثلا از ۱ تا ۸۹…اول اینکه میخوام بدونم ایا باید k رو هم به عنوان یه set در نظر بگیرم یا نه اگه اره به شکل زیر باید باشه؟؟؟

    t time period/1*96/
    

    K(t)/1*89/ درسته K(t) یا نیازی نست؟
    و دوم اینه یقینا دستور ordی که پایین نوشتم اشتباهه چون هدفم اینه که مقدار t رو برابر با حد پایین جمع Kباشه و حد بالاییش k+7 ولی نمیدونم باید چه جور نمایش بدم؟؟؟

    co117(t)$(ord(t) &gt;= K  and  ord(t)&lt;=K+7) .. sum(t,(Idg(t)+mdg(t)))=l=1;  
    

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

    1. محمودی

      سلام
      مچکرم بابت توضیحاتتون.
      k رو درست تعریف کردین. ولی بله فرمول مشکل داره. به شکل زیر بنویسین.
      co117(k) .. sum(t$(ord(t) >= ord(K) and ord(t)<=ord(K)+7),(Idg(t)+mdg(t)))=l=1;

  27. leila

    میبخشین یه سوال دیگه هم دارم..این heuristic still looking .( اجرای برنامه بهینه سازی MIP با سالور Cplex) واسه چیه؟البته بعدش جواب پیدا میکنه یعنی found incumbent دارم..

    1. محمودی

      سلام
      ببینین cplex وقتی مسئله رو حل میکنه از روشهای ابتکاری برای سریعتر حل کردن مدل استفاده میکنه. این heuristic… یعنی cplex مشغوله ابتکاریه ست هنوز.

  28. طاهر

    سلام من یک Table به صورت gg(g,l,f) دارم که مقادیر بین ۰ تا ۹ رو اختیار کرده

    f1 f2 f3

    g1.1 1.000 4.000 5.000
    g1.2 1.000 4.000 5.000
    g1.3 1.000 4.000 5.000
    g1.4 1.000 4.000 5.000
    g1.5 1.000 4.000 5.000
    g2.1 3.000 1.000 9.000
    g2.2 3.000 1.000 9.000
    g2.3 3.000 1.000 9.000
    g2.4 3.000 1.000 9.000
    g2.5 3.000 1.000 9.000
    g3.1 9.000 2.000 1.000
    g3.2 9.000 2.000 1.000
    g3.3 9.000 2.000 1.000
    g3.4 9.000 2.000 1.000
    g3.5 9.000 2.000 1.000
    حالا میخوام به این صورت این جدول تغییر کنه که به ازای هر اندیس l در ماتریس اگر مقدارش با مقدار اون درایه برابر بود بجای اون عدد مقدار یک رو قرار بده در غیر این صورت صفر باشه…یعنی عملا ماتریس نهایی باید ماتریس ۰ و ۱ دار بشه ..چطور باید دستورش در گمز نوشته بشه؟ ممنون میشم راهنمایی کنید
    ماتریس نهایی اینطوری باید بشه

    f1 f2 f3

    g1.1 1.000 0.000 0.000
    g1.2 0.000 0.000 0.000
    g1.3 0.000 0.000 0.000
    g1.4 0.000 0.000 0.000
    g1.5 0.000 0.000 1.000
    g2.1 0.000 0.000 0.000
    g2.2 0.000 0.000 0.000
    g2.3 1.000 0.000 0.000
    g2.4 0.000 0.000 0.000
    g2.5 0.000 0.000 0.000
    g3.1 0.000 0.000 1.000
    g3.2 0.000 1.000 0.000
    g3.3 0.000 0.000 0.000
    g3.4 0.000 0.000 0.000
    g3.5 0.000 0.000 0.000

  29. حمیدرضا

    پیاده سازی الگوریتم PSO در گمز چطوریه که کسی بلد نیست، اگه کسی اطلاعاتی داره لطفا راهنمایی کنه.
    ممنون

    1. یک بار برای همیشه
      GA, PSO, Hill Climbing, Simulated Annealing, Ant colony, leaping frog
      و هر آنچه heuristic می شناسید یا در آینده نزدیک خلق می شوند
      قابل پیاده سازی در GAMS نیستند
      البته هستند اما ارزش ندارد وقت خود را تلف کنبد
      مثل این می ماند بپرسید آیا می شود یک استخر آب را با چنگال خالی کرد ؟
      خیر /بلی به سختی !

  30. شهاب

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

  31. کاظم

    سلام. خسته نباشید
    من یه مدل ریاضی مشابه مدل زیر رو دارم که توش یه loop برای حل کردن مداوم مسئله نوشتم
    میخوام محاسبات رو انجام بده و در sqrtval بریزه و خروجی اکسل بهم بده. ولی خروجی اکسل خالیه و چیزی توش نمیاد.
    ممنون از زمانی که برای پاسخ دادن صرف میکنید

    Set i “set to drive iterations” / i-1*i-100
    /;
    Parameter value(i) “used to hold successive approximations”;
    Scalars target “number whose square root is needed” / 23.456 /
    sqrtval “final approximation to sqrt(target)”
    curacc “accuracy of current approximation”
    reltol “required relative accuracy” / 1.0e-06 /;

    abort$(target reltol),
    value(i+1) = 0.5*(value(i) + target/value(i));
    sqrtval = value(i+1);
    curacc = abs (value(i+1)-value(i))/(1+abs(value(i+1)))
    ) ;
    abort$(curacc > reltol) “square root not found”
    option decimals=8;
    display “square root found within tolerance”, sqrtval, value;
    execute_unload “result.gdx” sqrtval, value

    execute ‘gdxxrw.exe result.gdx o=result.xls var=sqrtval rng=result!b1:b7’

      1. کاظم

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

  32. BABAN

    چطور میشه پاسخ بدست آمده از حل معادله گمز مربوط به یافتن یک متغیر را در شرط عبارت دیگر استفاده نمود.
    یعنی اگر متغییر y بزرگتر از صفر باشد عبارت دیگری حل گردد و اگر کوچکتر از صفر باشد نیز عبارت دیگر اجرا گردد.
    ظاهرا از متغییر نمیشه در دستورات شرطی استفاده نمود.ممنون میشم راهنمایی فرمائئید.

    1. پاسخ شما را نمی توان در یک خط خلاصه کرد
      به صورت مختصر
      متغببر باینری به صورتی اضافه کنید که هر زمانی که y مثبت شد مقدارش برابر با ۱ بشود و اگر منفی شد ۰ بشود
      این متغییر باینری را به نحوی در مغادلات دخالت دهید که اگر ۱ بود معادله A فعال شود و اگر ۰ بود معادله B فعال شود
      مساله ممکنه است با افزودن این متغییر باینری minlp شود ! و حل آن سخت

  33. مهیار

    با سلام و وقت بخیر

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

    پیشاپیش بابت پاسخگوییتون متشکرم

    1. حلقه لوپتون رو مشابه جدولتون تعریف کنید
      یا می تونید بگید ord شمارنده لوپ شما با شماره ستون جدولتون یکی باشه

  34. saman mz

    سلام روز بخیر
    من یه سوال داشتم خدمتتون؛ من الان روی پروژه بهینه سازی کار میکنم که چند هدفه هستش و متغییر ها بر حسب t زمان , (سناریو) s هستن وتو قسمت solve که میخوام تابع هدف رو مینیموم کنم به روش محدودیت ارتقا یافته میخوام گمز برای هر سناریو و زمان ها(۲۴ ساعت ) مقدار تابع هدف مجزایی رو بده بهمون یعنی منظور به ازای s=1 و تایم های ۱ تا ۲۴ یک تابع هدف مینیموم شده مجزا بگیرم ممنون میشم راهنماییم کنین

    1. محمودی

      سلام
      اگه منظورتون augEps هست و دارین از کد اماده استفاده میکنین، اصلاج کد زمان بر هست مقداری. شاید بهتر باشه دونه دونه این داده ها رو به گمز بدین، و هر بار نتایج در اکسل ذخیره بشه. (که برای هر داده ی S,t چند جواب برای هر هدف خواهیم داشت نه یک تابع هدف مینیمم شده مجزا).
      اگرم یکی یکی نمیخواید اینکارو انجام بدین و دست به کدتون خوبه، دو تا loop بشت سر هم قبل از اولین دستور solve و بعد از اخرین دستور سالو کد اماده نیاز دارین. تشخیص نحوه دستکاری با شما.

  35. فراهانی

    با سلام و خسته نباشید
    من با نوشتن محدودیت حذف زیر تور در مساله مسیریابی وسایل نقلیه در گمز مشکل دارم. البته الگوریتم آن در متلب را می توانم بنویسم. محدودیت به این شکل است.
    u(i)-u(j)+n*x(i,j)<=n-1
    x(i,j) متغیر باینری است که در صورت سفر از i به j مقدار ۱ می گیرد.
    u(i) موقعیت شهر i را در تور سفر نشان می دهد. بعنوان مثال اگر u(3)=1 باشد، یعننی شهر ۳، اولین شهری است که بازدید خواهد شد.
    ممنون میشم راهنمایی بفرمایید.
    با تشکر

  36. مینا

    با سلام
    ایا در دستور loop می شود داده table از excel فراخوانی شود؟
    به عنوان مثال برای مسایل scenario-based که مدل باید به ازای هر سناریو ران شود.

    1. محمودی

      سلام
      بله.
      table اول باید تعریف شده باشه. بعدش داخل loop فرا خوانی انجام بشه.

  37. یلدا

    با عرض سلام و وقت بخیر
    ممنون میشم راهنمایی کنید رابطه زیر در گمز چطور نوشته میشه؟

    r(g)*u(g,t) sigma g sigma t
    به شرطی که ۱<t باشد( و نتوان t رو از سیگما تغییر داد.)
    تشکر

    1. محمودی

      سلام
      یعنی چه نتوان سیگما رو تغییر داد؟

      sum(g,t)$(ord(t)>1),r(g)*u(g,t))
      
  38. پریا

    سلام وقتتون بخیر و خسته نباشید .
    ببخشید من یک متغیر دارم (P(g,t که مقادیرش در زمان t1 مشخص هستش . (‘P(g,’t1 چطور می تونم این متغیر رو در لحظه اول مقداردهی کنم.

    ممنون می شم اگر راهنمایی بفرمایید.

    1. محمودی

      سلام
      قبل از دستور solve بنویسین: (مقدار مثلا ۱۰ باشه)

      p(g,'t1').fx=10;
      
  39. سمانه

    با عرض سلام
    من روی متعادلسازی خط مونتاژ u شکل کار میکنم و متغیر باینری (u(k رو برای ایستگاه k درنظرگرفتم. (x(t,k و (y(t,k هم متغیرهای باینری هستند بطوریکه فعالیت t به صورت فوروارد با x به ایستگاه k تخصیص پیدا میکنه و به صورت بکوارد با y به ایستگاه k تخصیص پیدا میکنه.
    کد گمزی که نوشتم برای مثال های مختلف حل کردم و مشکلی نبوده ولی به ازای یک مثال، بدون اینکه به ۳ تخصیصی انجام بده، مقدار (u(3 رو برابر یک میده.برای حل این مشکل میخوام بنویسم اگر مقدار عبارت روبرو بزرگتر از صفر بود، ( (sum(t,(x(t,k+(y(t,k
    مقدار (u(k رویک بده و اگر صفر بود، (u(k رو هم صفر بده.
    سعی کردم با ایف و لوپ بنویسم(با رعایت اینکه نباید داخلشون رابطه ای تعریف بشه) ولی نتونستم. ممنون میشم راهنمایی بفرمایید.

  40. عصمت

    سلام، یک مدل برای محاسبه هزینه سیستم دارم که بخشی از آن شامل شرط می باشد به این صورت که اگر مقدار موجودی باقیمانده در سیستم از مقدار تعیین شده بیشتر باشد هزینه آن محاسبه می شود در گمز چطور باید فرمول نویسی گردد؟
    همچنین ممنون میشم که بفرمایین که اگر سامیشن از ۱ تا n-1 باشد که n متغیر است را چطور تعریف کنیم؟

    1. محمودی

      سلام
      سوال اولتون مجهوله، منظورتون کجای مدله؟ تو محاسبات یا تو معادلات؟
      برای مورد دوم ایمیل بزنید به سایت و درخواست فایل حد بالای متغیر کنید که براتون ارسال بشه.

  41. آدینه

    سلام. وقت بخیر
    اگر امکانش هست چندتا مقاله در رابطه با انواع حلقه ها به همراه کد گمز برای اینجانب ایمیل کنید.
    متشکرم
    Solver BARON برا نرم افزار من دمو هست، برای حل مسائل غیرخطی به این Solver نیاز دارم. ممنون میشم راهنماییم کنید.

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