درس های موازی و تقریبی را دارد!
mycourse.blog.ir
http://graphics.stanford.edu/courses/cs468-06-winter/Slides/eugene_faster_core-set_winter.pdf
مدل جویبار داده (Streaming Model)
تعریف: یک الگوریتم stream الگوریتمی است که ورودی را در یک عبور (pass) می بیند و حافظه محدود دارد. {بهتر است بگوییم جویبار داده نامحدود است!}
*حل مساله قطر با جویبار داده
الگوریتم دقیق:
برای یک بعد: با محاسبه مینیمم و ماکسیمم با O(1) حافظه به دست می آید و با یک pass انجام پذیر است.
برای دو بعد: حداقل به اندازه ی تعداد نقاط حافظه نیاز داریم چون ممکن است نقطه ای که آن را حذف می کنیم (هر نقطه ای!) در آینده یکی از دو نقظه ی مرزی در محاسبه قطر نقاط باشد.
پس برای بیشتر از یک بعد نمی توانیم الگوریتم جویبار داده ی دقیق بدهیم.
الگوریتم تقریبی:
روش 0 (پیدا کردن دورترین نقطه از یک نقطه): O(1) حافظه می خواهد و در یک عبور امکان پذیر است.
روش 1 (پیدا کردن دورترین نقطه از یک نقطه و دورترین نقطه از آن): به دو عبور نیاز دارد. (نمی شود)
روش 2 (توری): نمی شود چون برای به دست آوردن تقریب اندازه خانه های توری (که گفتیم با یکی از الگوریتم های قبلی انجام می شود) به 2 عبور نیاز خواهد داشت.
روش 3 (رند کردن نقاط در جهت های مختلف): می شود چون بیشتر از یک عبور نیاز نداریم. حافظه ی O(1/epsilon^((d-1)/2)) می خواهد.
* مزیت الگوریتم 0 این است که در ابعاد بالا هم کار می کند، اما الگوریتم 3 نمایی است.
---------------------------------
*آیا می توان مساله نزدیک ترین دو نقطه را در مدل جویبار داده حل کرد؟ خیر، حتی نمی توان تقریب زد.
*آیا می توان مساله عرض نقاط را با این حل کرد؟ بله، با همان coreset گستره نقاط (extent)
*محاسبه عرض نقاط
الگوریتم 1: یک epsilon-هسته از نوع گستره نقاط پیدا کن
ایده: ادغام و کاهش (به آن روش لگاریتمی هم می گویند.)
اضافه کردن نقطه:
1) یک هسته شامل مجموعه تک عضوی {p} بساز. (سطح 0)
2) تا وقتی 2 هسته ی S1 و S2 به ترتیب برای مجموعه نقاط P1 و P2 وجود دارند و در یک سطح هستند:
2-1) اپسیلون هسته ی S که اجتماع S1 و S2 است محاسبه کن.
2-2) S را به عنوان هسته ی P1 U P2 در سطح i برچسب بزن. {حس می کنم اینجا باید i+1 باشه!}
2-3) S1 و S2 را حذف کن.
{جواب هم باید هسته ای باشه که در مرحله ی آخر =بالاترین سطح درخت باقی می ماند.}
دلیل نام گذاری این است که مجموعه نقاط هم سطح را ادغام می کند و وقتی برای سطح بالاتر هسته ساخت هسته های سطح پایین تر را حذف می کند.
{البته فکر کنم کاهش منظور همان ساختن هسته و کاهش نقاط است.}
تحلیل
تعداد سطح ها: O(log n)
فضای لازم: O(1/epsilon^d lg n) (اصطلاحاً polylog( n))
زمان: O(1/epsilon^d n)
( ضریب 1/epsilon^d از اندازه ی هسته می آید. lg n از عمق درخت. n از تعداد ادغام ها= کل گره های درخت)
دلیل حفظ ضریب تقریب هسته (هنگامی که دو هسته ادغام می شود) این است که هسته های قبلی نقاط مجزا داشته اند:
*اگر S1 یک اپسیلون-هسته برای P1 و S2 یک اپسیلون-هسته برای P2 باشد، S1 U S2 یک اپسیلون-هسته برای P1 U P2 است.
*اگر S یک اپسیلون-هسته برای Q باشد و Q یک اپسیلون پریم-هسته برای P باشد، آنگاه S یک (اپسیلون+اپسیلون پریم) - هسته برای P است.
(چون ضریب تقریب های آنها جمع می شود.)
در کل یک O(epsilon* log n)-هسته به دست می آید. اپسیلون را طوری تعیین می کنیم که log n حذف شود:
epsilon' = epsilon/lg n
و با این اپسیلون جدید هسته ها را به دست می آوریم.
فضای کل لازم O( 1/epsilon^(d-1) log^d n) است.
این مدل برای جویبار داده قابل استفاده هست اما می خواهیم مستقل از n کنیم.
23- نشان دهید چطور الگوریتم جمع carry-lookahead را تغییر دهیم تا یک عدد N بیتی را از یک عدد دیگر در زمان 2logN+2 قدم بیتی کم کند. می توانید از مکمل 2 استفاده کنید اما خروجی باید با فرمت ورودی باشد.
خود carry look ahead :
برای اینکه فرمت ورودی به هم نخورد، عملگر را از اول تعریف می کنیم:
1-1 = 0 , 0-0 = 0 ==> propagate (p)
0-1=1, carry(-1) ==> generate (g)
1-0 = 1 ==> stop (s)
بقیه مراحل الگوریتم مثل قبل است.
24- یک درخت دودویی کامل N-برگی داده شده است که هر برگ حافظه O(log N) بیتی دارد. نشان دهید چطور دو عدد N log N بیتی را روی این درخت با O( log N) قدم بیتی جمع کنیم. کارایی این الگوریتم چقدر است؟
تعداد برگها N/2 است پس در هر برگ log N/(N/2) = 2 log N بیت از جواب قرار می گیرد. carry ایجاد شده در هر برگ مثل سوال قبل محاسبه می شود.
E = T_best_serial/W_parallel = N log N / (log N * N) = 1
25- نشان دهید چطور یک الگوریتم موازی پیشوندی (parallel prefix) را روی یک درخت سه تایی انجام دهیم. تعمیم الگوریتم برای درخت d-تایی چطور خواهد بود؟ (d>3)
در هر گره باید به صورت سریال عملیات را روی فرزندان انجام بدهیم. عمق درخت لگاریتم در مبنای d خواهد شد ولی زمان محاسبه سریال d عنصر هم در زمان ضرب می شود که در کل همان مرتبه لگاریتمی است.
26- چقدر طول می کشد که دو عدد N بیتی را روی یک آرایه sqrt(N)*sqrt(N) ضرب کنیم؟
با روش مارپیچی (که سطرهای زوج را صعودی و سطرهای فرد را نزولی مرتب می کردیم و بعد ستونها را صعودی مرتب می کردیم و تکرار) بار اول نصف کمتر و بیشتر اعداد مشخص می شد و همین کار تکرار می شد. کلا log (sqrt(N)) = O(log N) بار تکرار لازم است هر بار یک مرتب کردن هم داریم که O(sqrt(N)) طول می کشد پس کلاً O(sqrt(N) log(N)) زمان می خواهد.
27- الگوریتم پیشوندی موازی (parallel prefix) قسمت 1.2.2 را تغییر دهید تا پسوند حساب کند.
فاز اول تغییری نمی کند، فاز دوم را به جای اینکه سمت چپ ترین مسیر را به همه ی زیر درخت های سمت راست بفرستیم، سمت راست ترین مسیر را به همه ی زیردرخت های چپ می فرستیم.
شکل پیشوندی: (آخرین شکل: هر گره از بالا پسوند سمت راستی را می گیرد و مقدار خودش را به اول آن اضافه می کند.)
28- مساله توزیع داده شامل توزیع مقدار مشخصی داده بین مجموعه ای از پردازنده ها است. به ما مقدار عمق درخت دودویی (D) و m مقدار v1,...,vm داده شده است. هر برگ درخت یا شامل یک درخواست ri برای مقدار i-ام است یا خود مقدار v_i. به علاوه ما فرض می کنیم همه درخواستهای مقدار i بلافاصله بعد از خود مقدار i آمده اند. مثلا در شکل 1-119. مساله توزیع vi به هر برگ متقاضی آن است. نشان دهید چطور این کار در O(D) گام ممکن است، اگر در ابتدای کار ندانیم کدام برگ ها درخواست اند و کدام برگ ها مقادیر هستند.
(راهنمایی: از پیشوند موازی استفاده کنید.)
(الآن به ذهنم رسید یک سری از حل های قبلی باید غلط باشند چون من بیشتر از یک داده از یک لینک رد می کردم!!)
اول کران پایین را برای این مساله حساب می کنیم:
bisection width = 2 ==> lower_bound1 = 2m/2 = O(2*2^d/2) = O(2^d)
diameter = 2d ==> lower_bound2 = 2d
==> lower bound = max(m,2d)
به ازای d>5 مقدار کران پایین مساله برای درخت دودویی کامل از O(d) که سوال خواسته است بیشتر می شود. پس با عملیات کلمه ای این مساله حل نمی شود.
باید از ایده ای مشابه مرتب سازی استفاده کنیم، در آنجا کاری که می کردیم به این کار خیلی شبیه بود، فقط از اول جای نهایی اعداد را می دانستیم که اینجا می توانیم آن را با عملیات پیشوندی موازی به صورت بیتی به دست بیاوریم. یک عدد m بیتی بگیریم که هر بیت آن بودن یک درخواست را نشان می دهد و برای محاسبه ی مقدار ریشه آن را or کنیم. در هر زیردرختی فقط مقداری را می فرستیم که درخواست شده باشد و این کار را هم به صورت بیتی انجام می دهیم. ؟؟ یادم نیست در مرتب سازی چطور اعداد را جا به جا می کردیم؟!
29- دو مساله پیشوندی با N ورودی داده شده اند، نشان دهید چطور آنها می توانند به صورت یک مساله پیشوندی موازی (اما پیچیده تر) حل شوند.
هر بار در هر پردازنده دو تا مقدار نگه داریم که هر کدام مربوط به یکی از مسائل است.
30- نشان دهید چطور مقایسه دو عدد N بیتی می تواند توسط محاسبه پیشوندی موازی انجام شود.
عملگر مقایسه را روی زیرمجموعه های دو عدد انجام می دهیم و هر عددی که پیشوند آن بزرگتر بود بزرگتر است. (چون پیشوند رقمهای پرارزش است).
31- نشان دهید که الگوریتم دو مرحله ای زیر پیشوندها را روی درخت دودویی حساب می کند. در ورودی i-امین برگ xi را ذخیره می کند. در فاز حرکت به سمت بالا هر گره میانه مقدار فرزند چپ خود را ذخیره می کند و concat مقادیر فرزندانش را به پدرش می فرستد. در فاز حرکت به سمت پایین هر گره میانی مقداری که از پدرش دریافت کرده به فرزند چپش می فرستد و concat مقدار پدرش را با مقدار خودش را به فرزند راستش می فرستد. (شکل 1-120)
قرار بود در مورد LSH ارائه بدهم، سری قبل انقدر نمره کم گرفته بودم که اصلا دلم نمی خواد برم ارائه بدم حتی! ترجیح می دهم همینجا بگذارمش.
دریافت
حجم: 1.22 مگابایت
1- نشان دهید اگر وزن یالی در نامساوی مثلث صدق نکند، آنگاه مساله k-مرکز نمی تواند تقریبی بهتر از a(n) برای هر تابع a(n) قابل محاسبه داشته باشد.
راهنمایی: از ایده قضیه 3.6 و 5.7 استفاده کنید.
5.7 = dominating set، یالهای گراف 1، یالهای دیگر 2
3.6 = وجود جواب برای مساله: هزینه ی n، عدم وجود جواب: هزینه a(n).n
حل:
*حل دستگاه ماتریس پایین مثلثی
مشابه ضرب ماتریس و بردار عمل می کنیم (ماتریس A و بردار x) و حاصل جمع را حساب می کنیم. حالا باید ti را حساب کنیم، چون بین مقادیر دیگر فاصله گذاشتیم بین ti ها هم باید فاصله بگذاریم تا جواب درست به دست بیاید. ؟؟
مراحل این کار را در شکل زیر بهتری می بینید. به ترتیب مقادیر xi محاسبه می شوند و به سمت راست می روند و در درایه های ماتریس سطر بعد ضرب می شوند (و همزمان باز هم به راست می روند تا درایه های بعدی را بسازند) و از مقدار قبلی ti کم می شوند و ti جدید به سمت چپ می رود تا مقدار xi بعدی محاسبه شود.
*ضرب ماتریس در بردار
برای ضرب ماتریس در بردار، باید هر سطر آن را در بردار ضرب کنیم. جواب ما یک بردار n بیتی است پس می توانیم با n پردازنده آن را به دست بیاوریم (در هر پردازنده یک درایه ی آن را نگهداری کنیم). مثل قبل عمل جمع ساده است؛ اعمال ضرب لازم برای هر درایه، ضرب هر عدد از بردار در هر عدد از سطر j-ام ماتریس است، (به همان ترتیب خودشان). پس به پردازنده j-ام بردار و سطر j-ام ماتریس وارد می شوند. (مستقل از بقیه پردازنده ها). شکل زیر این کار را نشان می دهد:
* ضرب دو ماتریس
برای ضرب دو ماتریس هر سطر اولی باید در هر ستون دومی ضرب شود و می توانیم ماتریس دوم را به صورت n تا بردار در نظر بگیریم و همان روش ضرب ماتریس در بردار را روی آنها انجام دهیم.
* ضرب ماتریس و بردار با مدل حلقه
باید داده های تکراری را به دست بیاوریم. بردار به ازای هر سطر ماتریس یکبار استفاده می شود. در مدل آرایه خطی بردار یک بار دیده می شد، پس باید تاخیر ایجاد می کردیم تا همزمان به هم برسند. اما در مدل حلقه می توانیم با یک اندیس جا به جا کردن از هر پردازنده به پردازنده ی بعد این مشکل را حل کنیم. (چون داده دوباره بر می گردد و تا زمانی که درایه بردار به آن پردازنده برسد، درایه مناسب ماتریس هم به آن وارد می شود.)
* ضرب دو ماتریس در مدل حلقه
از ضرب ماتریس و بردار در حلقه استفاده می کنیم و هر ستون ماتریس دوم را مثل یک بردار می گیریم.
*کلا ایده ی اصلی این است که مقدار هر پردازنده (جواب) را بنویسیم و با توجه به آن سیستم را طراحی کنیم.