ورود

View Full Version : کاهش زمان اجرای کد در متلب



imnox66
شنبه 16 خرداد 1394, 00:18 صبح
سلام من دو تا محدودیت به صورت عکس زیر دارم. تعریف محدویت ها به این صورته :
131981
توالی انجام کارها روی یک ماشین را نشان می دهد یعنی دو کاری که روی یک ماشین انجام می شود. چنانچه Hijlhrpk = 0 شود یعنی زیرکار i از کار j و زیرکار l از کار h هر دو بر روی ماشین شماره r از نوع p در سرور k انجام نشوند عبارت (1 – Hijlhrpk) برابر با یک خواهد شد که در نتیجه ی ضرب این عبارت با M که یک مقدار بسیار بزرگ می باشد، باعث می شود این دو محدودیت، غیرفعال تلقی شوند. حال اگر Hijlhrpk = 1 شود، دو حالت در مورد اولویت زیرکارهای i و l از کارهای j و h پیش می آید :
الف) اگر Wijlh = 1 شود، یعنی زیرکار i از کار j زودتر از زیرکار l از کار h انجام شود، در این صورت زمان تکمیل زیرکار l از کار h باید از زمان پردازش زیرکار i از کار j بزرگتر مساوی باشد. ضمنا محدودیت (19) نیز غیرفعال تلقی می شود.
ب) اگر Wijlh = 0 شود، یعنی زیرکار l از کار h زودتر از زیرکار i از کار j انجام شود، در این صورت زمان تکمیل زیرکار i از کار j باید از زمان پردازش زیرکار l از کار h بزرگتر مساوی باشد. ضمنا محدودیت (18) نیز غیرفعال تلقی می شود.


من کدم رو به صورت زیر نوشتم. اما زمان اجرای این حلقه خیلی طولانیه. من چطوری می تونم کدم رو بهینه کنم و زمان اجرای اون رو کاهش بدم؟؟


for k=1:c for p=1:m
for r=1:N(p,k)
for j=1:t
for h=1:t
if j==h
continue;
end
for i=1:s
for l=1:s
if Z(i,j,r,p,k)==Z(l,h,r,p,k)
H(i,j,l,h,r,p,k)=1;
Q11=W(i,j,l,h)+WW(l,h,i,j);
V(9)=abs(Q11/H(i,j,l,h,r,p,k)-1);

if W(i,j,l,h)==1
Q12=gs(l,h)-gs(i,j);
V(10)=max(0,1-Q12/Pt(l,h,p));

else

Q13=gs(i,j)-gs(l,h);
V(10)=max(0,1-Q13/Pt(i,j,p));
end

end
end
end
end
end
end
end
end

rahnema1
یک شنبه 17 خرداد 1394, 10:10 صبح
سلام
ابعاد این i و j وs و.. چند در چند هست؟ چون اگه کم باشه میشه سرعت را بالا برد

imnox66
دوشنبه 18 خرداد 1394, 21:06 عصر
سلام
ابعاد این i و j وs و.. چند در چند هست؟ چون اگه کم باشه میشه سرعت را بالا برد


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

rahnema1
سه شنبه 19 خرداد 1394, 07:01 صبح
مثلا یه همچین چیزی می شه نوشت

[h0 l0] = meshgrid(1:t, 1:s);
for j0=1:t
l = l0(:, 2:end);
h = h0(:, [1:(j0-1) (j0+1):end]);
for p0=1:m
for k0=1:c
for r0=1:N(p0,k0)
for i0=1:s
r = repmat(r0 , size(h));
p = repmat(p0 , size(h));
k = repmat(k0 , size(h));
fnd = find(Z(sub2ind(size(Z), l,h,r,p,k)) == Z(i0,j0,r0,p0,k0));
if numel(fnd) > 0
l = l(fnd);
h = h(fnd);
i = repmat(i0 , size(h));
j = repmat(j0 , size(h));
r = repmat(r0 , size(h));
p = repmat(p0 , size(h));
k = repmat(k0 , size(h));
indH = sub2ind(size(H), i,j,l,h,r,p,k);
H(indH)=1;
indW = sub2ind(size(W),i,j,l,h);
Q11=W(indW) + WW(indW);
V{1}=abs(Q11 ./ (H(indH)) - 1);
W12 = find(W(indW) == 1) ;
W13 = find(W(indW) ~= 1);
Q1213 = gs(sub2ind(size(gs),l,h)) - gs(i0,j0);
Pt12 = Pt(sub2ind(size(Pt),l,h,p));
Q1213(W12) = Q1213(W12) ./ Pt12(W12);
Q1213(W13) = -Q1213(W13) ./ Pt(i0,j0,p0);
V{2}=max(0, 1 - Q1213);
end
end
end
end
end
end

imnox66
سه شنبه 19 خرداد 1394, 13:30 عصر
مثلا یه همچین چیزی می شه نوشت

[l0 h0] = meshgrid(1:s, 1:t);
for j=1:t
l = l0[1:j-1 j+1:end];
h = h0[1:j-1 j+1:end];
for p=1:m
for k=1:c
for r=1:N(p,k)
for i=1:s
fnd = find(Z(l,h,r,p,k) == Z(i,j,r,p,k));
l = l(fnd);
h = h(fnd);
H(i,j,l,h,r,p,k)=1;
Q11=W(i,j,l,h)+WW(l,h,i,j);
V(9)=abs(Q11 ./ H(i,j,l,h,r,p,k) - 1);
W12 = find(W(i,j,l,h) == 1) ;
W13 = find(W(i,j,l,h) ~= 1 );
Q1213 = gs(l,h)-gs(i,j);
Pt12 = Pt(l,h,p);
Q1213(W12) = Q1213(W12) ./ Pt12(W12);
Q1213(W13) = -Q1213(W13) ./ Pt(i,j,p);
V(10)=max(0, 1 - Q1213);
end
end
end
end
end



خیلی سپاسگذارم از پاسختون. میشه بگید کدهای مربوط به l و h در خطوط ابتدایی کد، دقیقا چی کاری انجام میده؟ چون من وقتی کدو توو متلب وارد کردم ارور داد.

rahnema1
سه شنبه 19 خرداد 1394, 18:16 عصر
ببخشید. اشتباه در کد را اصلاح کردم. حالا امتحان کنید ببینید اشکالی وجود نداره؟

imnox66
سه شنبه 19 خرداد 1394, 23:06 عصر
ببخشید. اشتباه در کد را اصلاح کردم. حالا امتحان کنید ببینید اشکالی وجود نداره؟

چرا بازم ارور می ده. فکر می کنم l و h بیشتر از یه مقدار رو برمی گردونند. چون وقتی به خط (Q11=W(i,j,l,h)+WW(l,h,i,j می رسه این ارور رو می ده که برای + باید ابعاد ماتریس ها با هم برابر باشه.

rahnema1
سه شنبه 19 خرداد 1394, 23:11 عصر
بله l و h بیشتر از یک مقدار بر می گردونند. لازمه سایز اونها متناسب با هم بشن. اگه بتونید w و ww را جوری بنویسید که ترتیب i وj و l و h در هر دو یکسان باشه فکر کنم خطا بر طرف می شه

imnox66
سه شنبه 19 خرداد 1394, 23:40 عصر
بله l و h بیشتر از یک مقدار بر می گردونند. لازمه سایز اونها متناسب با هم بشن. اگه بتونید w و ww را جوری بنویسید که ترتیب i وj و l و h در هر دو یکسان باشه فکر کنم خطا بر طرف می شه

ببخشید متوجه منظورتون نشدم. یعنی چی به ترتیب بنویسمشون؟

rahnema1
چهارشنبه 20 خرداد 1394, 05:45 صبح
دوباره اصلاح کردم ببینید درست می شه

imnox66
چهارشنبه 20 خرداد 1394, 12:11 عصر
دوباره اصلاح کردم ببینید درست می شه

اروری که باز میده اینه :
Index exceeds matrix dimensions.
Error in test
l=l(fnd); d

rahnema1
چهارشنبه 20 خرداد 1394, 18:46 عصر
باز هم اصلاح کردم
در کل توصیه می کنم برای برنامه هایی که زمان بر هستند به جای متلب از زبانهای دیگه مثل ++c یا زبانهای سریع دیگه استفاده بشه

imnox66
جمعه 22 خرداد 1394, 23:02 عصر
باز هم اصلاح کردم
در کل توصیه می کنم برای برنامه هایی که زمان بر هستند به جای متلب از زبانهای دیگه مثل ++c یا زبانهای سریع دیگه استفاده بشه

متأسفانه بازم ارور داد :ناراحت:


Error using sub2ind (line 72)Out of range subscript.


Error in InternalCost (line 194)
indH = sub2ind(size(H), i,j,l,h,r,p,k);

imnox66
جمعه 22 خرداد 1394, 23:25 عصر
باز هم اصلاح کردم
در کل توصیه می کنم برای برنامه هایی که زمان بر هستند به جای متلب از زبانهای دیگه مثل ++c یا زبانهای سریع دیگه استفاده بشه

بعد یه چیز دیگه، اینکه می گید از یه زبان دیگه استفاده کنم، من کلی وقت گذاشتم چند هزار خط کدمو توی متلب نوشتم. الان می گید کل شو ببرم توو یه زبان دیگه پیاده کنم؟؟ همه ی زمان اجرای کد من برای این حلقه ها گرفته میشه. اگه این حلقه بهینه بشه دیگه مشکلی نیست.
من بررسی کردم اگه به جای H(i,j,l,h,r,p,k) تنها از H استفاده کنم مشکلی پیش نمیاد. چون قرار نیست جای دیگه ازش استفاده کنم. هر بار اگه Z(l,h,r,p,k) == Z(i,j,r,p,k) باشه مقدار H رو 1 می کنه و بقیه دستورات رو اجرا می کنه. تداخلی هم پیش نمیاد. اینجوری زمان اجرای حلقه کمتر میشه. اما باز بیشتر سر بررسی شرطی که نوشتم زمان گرفته میشه

rahnema1
جمعه 22 خرداد 1394, 23:25 عصر
حالا شما که در خصوص متغیرها چیزی نگفتید من با حدس خودم این متغیرها را ساختم و روی اونها تست کردم و اجرا شد. معمولا قانون سوال پرسیدن اینه که کسی که سوال می پرسه یک برنامه قابل اجرا را میذاره که دیگران بتونند کاملا اجرا کنند اما شما یه تیکه کد از وسط یه برنامه بیرون کشیدید من هم با حدس خودم تغییر میدم کم کم به حل معمای شما نزدیک می شیم :)

t= 5;
s= 8;
m= 3;
c= 4;
N= randi( [1 10],m,30);
Z = randi([1 10], s, t,10,m,c);
H= zeros(s,t,s,t,10,m,c);
W=randi([0 1],s, t,s,t);
WW=randi([0 1],s, t,s,t);
gs=rand(s ,t);;
Pt=rand(s, t,m);

imnox66
شنبه 23 خرداد 1394, 00:29 صبح
حالا شما که در خصوص متغیرها چیزی نگفتید من با حدس خودم این متغیرها را ساختم و روی اونها تست کردم و اجرا شد. معمولا قانون سوال پرسیدن اینه که کسی که سوال می پرسه یک برنامه قابل اجرا را میذاره که دیگران بتونند کاملا اجرا کنند اما شما یه تیکه کد از وسط یه برنامه بیرون کشیدید من هم با حدس خودم تغییر میدم کم کم به حل معمای شما نزدیک می شیم :)

t= 5;
s= 8;
m= 3;
c= 4;
N= randi( [1 10],m,30);
Z = randi([1 10], s, t,10,m,c);
H= zeros(s,t,s,t,10,m,c);
W=randi([0 1],s, t,s,t);
WW=randi([0 1],s, t,s,t);
gs=rand(s ,t);;
Pt=rand(s, t,m);



واقعا از این همه وقتی که می زارید بی نهایت سپاسگذارم.
من کدم حداقل 10 تا تابع داره و این تابع هزینه هم که بخشی از اون رو نوشتم 400 و خورده ای خط میشه. همه ای این متغیرها و پارامترهایی که محبت کردید و زحمت کشیدید نوشتید توی یه تابع دیگه به دست میاد و یا تعریف شده. Z و W و WW و H متغیر تصمیم هستند و بقیه پارامتر. V هم آرایه ای هست که مقدار تخطی ها رو توی خودش نگه می داره. بعد اینکه شما به صورت V{1} می نویسید ارور می گیره. :عصبانی++:

rahnema1
شنبه 23 خرداد 1394, 18:16 عصر
من ابتدا فرض کردم V یک سلول خالی هست یعنی در ابتدا V را اینجور قرار دادم
V={};

imnox66
شنبه 23 خرداد 1394, 23:41 عصر
من ابتدا فرض کردم V یک سلول خالی هست یعنی در ابتدا V را اینجور قرار دادم
V={};

من باید مقادیر این ماتریس یا به قول شما سلول رو با هم جمع کنم و همین طور تعداد مقادیر غیر صفرش رو بشمارم. وقتی از sum(cell2mat(V)) استفاده می کنم ارور می ده که محتویات سلول باید از یک نوع باشه.

rahnema1
شنبه 23 خرداد 1394, 23:46 عصر
من باید مقادیر این ماتریس یا به قول شما سلول رو با هم جمع کنم و همین طور تعداد مقادیر غیر صفرش رو بشمارم. وقتی از sum(cell2mat(V)) استفاده می کنم ارور می ده که محتویات سلول باید از یک نوع باشه.

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

imnox66
یک شنبه 24 خرداد 1394, 00:33 صبح
دوست عزیز الان این یه معمای جدیده؟ آخه این V که مرتبا داره توی حلقه تغییر می کنه. اصلا ذخیره اش هیچ فایده ای نداره

من V رو دقیقا جایی تعریف کردم که مقدار نهاییش توی یه محدودیت، باید ذخیره شه. هر کدوم از درایه های این ماتریسی که من تعریف کردم مربوط به تخطی یه محدودیت خاصه.

rahnema1
یک شنبه 24 خرداد 1394, 07:19 صبح
ببینید اگه مقدار نهایی V را می خواهید دیگه لازم نیست داخل for مقدار دهی کنید وقتی for های تو در تو تموم شد شما این را بذارید

V{1}=abs(Q11 ./ (H(indH)) - 1);
V{2}=max(0, 1 - Q1213);