۷۱

انواع حلقه در گمز | 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);

]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • مثال زیر بهتون کمک میکنه:
      [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[

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

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

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

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

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

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

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

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

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

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

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

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

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

  10. سلام من ی کد تو گمس نوشتم که کاراییی ۱۲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 رو نمیتونم انجام بدم
    مرسی

    • سلام
      شما باید اول 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;
      );
      
  11. با سلام.
    میخوام کد دستور 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هم ارسال کنید.با سپاس

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

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

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

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

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

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

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

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

  16. سلام
    من یک پارامتر دارم که قبل از ورود به 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;
    

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

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

    /۵*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
    
                  );
                 );
    
    • سلام
      تو 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;
      
      ););
      
      
  18. سلام…
    تو دستور زیر که من i , j رو قبلا alias کردم و i و j برابر می شوند
    (f(i,j) =e= (v(i)-v(j))/z(i,j
    معادله مربوط به جریان است و صفر می شه و گمز ارور صفر شدن عبارت رو میده
    می خوام بگم در زمان هایی که iو j مخالفند فرمول رو اجرا کنه.. چطوره؟
    سوال دوم .. قبل عبارت بالا هم میخوام بگم وقتی از i به j خطی وجود داره ( که z وجود داشته باشه) فرمول رو اجرا کنه
    جدول z قبلا معرفی شده
    با تشکر

  19. با سلام و خسته نباشید
    اگر امکان داشته باشد لطفا در نوشتن کد مسئله زیر به بنده کمک کنید
    مسئله بصورت زیر است:
    زمان بصورت مجموعه تعریف شده است: / 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 باشد.
    با تشکر

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

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

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

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

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

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

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

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

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

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

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

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

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

          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 هم که طبق فرمول محاسبه میشه.

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

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

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

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

          
          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;
          
          
        • با سلام
          خیلی خیلی سپاسگزارم از جنابعالی. اگر امکان داشته باشد لطفا به این سوال هم جواب بدید.
          اگر خروجی بجای اعداد ۲، ۴، ۶، ۸ و ۱۰ ، به ترتیب اعداد ۱۰، ۱۳، ۱۵، ۱۶ و ۱۷ را تولید کند نامساویها چگونه تغییر می کنند؟
          منظورم اینست که خروجی از یک رابطه خاصی تبعیت نکند.
          خیلی ممنونم از شما

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

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

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

  21. سلام و وقت به خیر..سوالی داشتم ممنون میشم پاسخ بدین..میخوام یه محدودیتی تعریف کنم به این مفهوم که حاصل 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;  
    

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

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

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

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *