الگوریتم ضرب

**الگوریتم ضرب** مجموعه‌ای از دستورالعمل‌های محاسباتی خوش‌تعریف است، که به وسیلهٔ آن می‌توان حاصل ضرب دو عدد را بدست آورد. الگوریتم‌های مختلفی برای ضرب دو عدد ارائه داده شده‌اند که با توجه به طول اعداد و مکان استفاده از آن‌ها از الگوریتم‌های مختلف استفاده می‌کنیم.

## شیوه‌های باستانی ضرب دو عدد
### شیوهٔ ضرب در مصر باستان
نام دیگر این روش شیوهٔ ضرب روستاییان است. در مصر باستان مردم شیوهٔ جالبی برای ضرب اعداد استفاده می‌کردند، که بر مبنای مضرب دو اعداد کار می‌کرد. در این روش جدولی از اعداد تشکیل می‌دهیم و در سطر اول آن عدد یک و عدد ضرب‌کننده را می‌نویسیم. در هر سطر بعدی عدد سطر بالا را در دو ضرب می‌کنیم و این کار را آنقدر ادامه می‌دهیم تا اولین عدد سطر از ضرب‌شونده (مضروب) بیشتر شود. حال در ستون اول اعدادی که ضرب‌شونده را با عملگر جمع می‌سازند می‌یابیم. با جمع مقادیر پیدا شده حاصل ضرب اعداد را بدست می‌آوریم.

برای مثال اگر بخواهیم حاصل ضرب ۳۱ در ۴۲ را بدست آوریم جدولی به صورت زیر تشکیل می‌دهیم.
  ۳۱ ۱
  ۶۲ ۲
  ۱۲۴ ۴
  ۲۴۸ ۸
  ۴۹۶ ۱۶
  ۹۹۲ ۳۲
  ۱۹۸۴ ۶۴ 
پرونده:Sticks2.jg.jpg|چینیان باستان برای ضرب دو عدد از شیوه‌ای تصویری استفاده می‌کردند. برای مثال اگر بخواهیم دو عدد ۱۶ و ۲۴ را در هم ضرب کنیم
حال تعداد برخورد خط‌ها با یک‌دیگر را بررسی می‌کنیم. اگر هر ردیف از راست به چپ نشان‌دهندهٔ یک ارزش مکانی باشد، می‌توانیم حاصل ضرب را پیدا کنیم. برای این مثال ۲۴ برخورد در ردیف ارزش مکانی یکان اتفاق افتاده است. یعنی ارزش یکان ۴ است و به ارزش دهگان ۲ واحد اضافه می‌کنیم. تعداد برخوردها در ردیف ارزش دهگان ۱۶ است و ۲ واحد هم از یکان اضافه شده پس به ارزش دهگان ۸ است و یک واحد به صدگان اضافه می‌کند. به همین طریق ارزش صدگان ۳ است. پس حاصل ضرب اعداد مثال‌زده‌شده ۳۸۴ است.
پرونده:AfterConflict.jpg|تعداد برخوردها با توجه به ارزش مکانی آن‌ها در تصویر نشان داده شده‌است.


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

به عنوان مثال جدول شبکه‌ای ضرب دو عدد ۳۵ و ۲۶ به صورت زیر است.

با توجه به جدول بالا حاصل ضرب دو عدد ۳۵ و ۲۶ به صورت جمع زیر است.
 ۹۱۰ = ۳۰ + ۱۸۰ + ۶۰۰ + ۱۰۰ = ۳۵ × ۲۶

## ضرب طولانی
این روش ضرب کردن همان روشی است که در مدارس به دانش‌آموزان تدریس می‌شود. این روش برای ضرب اعداد بزرگ در هم کارآمد است.

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

### مثال
برای ضرب دو عدد ۲۳۹۵۸۲۳۳ و ۵۸۳۰ در هم اعداد را به صورت زیر نوشته و حاصل ضرب را بدست می‌آوریم.
  ۲۳۹۵۸۲۳۳
  ۵۸۳۰ ×
  ———————————————
  ۰۰۰۰۰۰۰۰ (= ۲۳٬۹۵۸٬۲۳۳ × ۰)
  ۷۱۸۷۴۶۹۹ (= ۲۳٬۹۵۸٬۲۳۳ × ۳۰)
  ۱۹۱۶۶۵۸۶۴ (= ۲۳٬۹۵۸٬۲۳۳ × ۸۰۰)
  ۱۱۹۷۹۱۱۶۵ (= ۲۳٬۹۵۸٬۲۳۳ × ۵٬۰۰۰)
  ———————————————
  ۱۳۹۶۷۶۴۹۸۳۹۰ (= ۱۳۹٬۶۷۶٬۴۹۸٬۳۹۰)

### محاسبهٔ پیچیدگی الگوریتم طولانی ضرب
اگر دو عددی که در هم ضرب می‌کنیم به طول n بود در هر مرحله n ضرب انجام می‌دهیم و تعداد مراحل n است، پس پیچیدگی این الگوریتم o(n^2)است.

## ضرب با استفاده از جدول مشبکی
شیوه‌ای برای ضرب کردن است که از یک جدول مشبکی استفاده می‌کند. این شیوه در زمان قرون وسطی به‌وجود آمده و در سرزمین‌های مختلفی از آن استفاده می‌شد. امروزه نیز این روش در برنامهٔ درسی بعضی کشورها تدریس می‌شود.

در این روش یک جدول مشبکی کشیده می‌شود و رقم‌های دو عددی که می‌خواهیم آن‌ها را در هم ضرب کنیم در بالا و سمت راست جدول کشیده می‌شود. جدول مشبکی ضرب دو عدد ۵۸ و ۲۱۳ به صورت زیر (تصویر مرحلهٔ اول) است. ما باید هر خانهٔ آن را به صورتی پر کنیم که با ضرب عدد بالای ستون و سمت راست سطر یکان عدد حاصل در پایین و دهگان آن در بالای خط موجود در خانه نوشته شود.
پرونده:Example of step 1 of lattice (shabakh) multiplication algorithm.svg|مرحلهٔ اول
پس از پر کردن تمامی خانه‌های جدول، جدول به تصویر مرحلهٔ دوم تبدیل می‌شود؛ که بعد از این مرحله باید از پایین راست جدول به سمت بالا حرکت کنیم و سپس به سمت چپ برویم و در هر مرحله جمع خانه‌های مثلثی همسایه (خانه‌های همسایه مثلث‌هایی هستند ساق‌هایشان مشترک است) را حساب کنیم. اگر این جمع بیشتر از نه شد یکان آن را نوشته و عدد دهگان را با عدد مرحلهٔ بعد جمع می‌کنیم.
پرونده:Example of step 2 of lattice (shabakh) multiplication algorithm.svg|مرحلهٔ دوم
در آخر تصویر جدول به شکل جدول آمده در مرحلهٔ سوم است.
پرونده:Example of step 1-3 of lattice (shabakh) multiplication algorithm..svg|مرحلهٔ سوم
همان‌طور که مشاهده می‌کنید جواب بدست آمده ۱۲۳۵۴ است.

## الگوریتم‌های سریع ضرب برای ورودی‌های بزرگ
### [[الگوریتم کاراتسوبا]]
**الگوریتم کاراتسوبا** یک الگوریتم سریع برای ضرب است که از الگوریتم تقسیم و حل برای ضرب دو عدد استفاده می‌کند. اگر x و y بیانگر دو عدد در مبنای b به طول n باشند، ما هر کدام از این اعداد را به دو قسمت پرارزش(H) و کم ارزش (L) تقسیم می‌کنیم. به این ترتیب حاصل ضرب به صورت زیر می‌شود.

X = XH b(n/2) + XL

Y= YH b(n/2) + YL

(XY = (XH b(n/2) + XL) (YH b(n/2) + YL

XY = xHyHbn + (xHyL + xLyH)b(n/2) + xLyL

به این ترتیب مسئله به چهار زیرمسئله تقسیم می‌شود؛ و این تقسیم ادامه پیدا می‌کند تا به زیرمسئله‌های ساده‌برسد. حاصل ضرب به صورت بازگشتی به دست می‌آید.

با یک راه حل ساده می‌توان تعداد ضرب‌های انجام شده (زیرمسئله‌ها) را از ۴ به ۳ رساند.

a = x_H \times y_H

d = x_L \times y_L

e = (x_h + x_l)(y_h + y_l) - a - d

xy = ab^n + eb^{n/2} + d

با داشتن a و b می‌توان تنها با استفاده از ۳ جمله این ضرب را انجام داد.

#### مثالی برای الگوریتم کاراتسوبا
فرض کنید می‌خواهیم عدد ۱۲۳۴ را در ۴۳۲۱ ضرب کنیم. برای اینکار به صورت زیر عمل می‌کنیم.

x = 1234

y = 4321

n = 4

ابتدا a و b و e را بدست می‌آوریم.

a=12 \times43

d=34 \times21

e = (12 + 34)(43+21) - a - d

حال بدست آوردن هر کدام از این ضرب‌ها خود یک زیر مسئله است. برای بدست آوردن حاصل ضرب ۱۲ و ۴۳ داریم

a=1 \times 4 = 4

d=2 \times3 = 6

e = (1+2)(4+3) - 4 - 6 = 11

12 \times 43 = 4\times10^2 + 11\times10+6 = 516

به همین روش برای مسئلهٔ اصلی ۷۱۴ = d و e با توجه به مقدار بدست آمده برای a و d، برابر ۱۷۱۴ است.

پس نتیجه می‌شود که

1234 \times 4321 = 516\times10^4 + 1714\times10^2+714 = 5332114

#### تحلیل زمان اجرای الگوریتم
این الگوریتم هر مسئله را به ۳ زیر مسئله به طول نصف مسئله-- قبلی تقسیم می‌کند پس زمان اجراء آن به صورت زیر است.

T(n)=3T(n/2)+O(n)

با توجه به قضیه اصلی در الگوریتم‌ها می‌توانیم زمان اجرای این الگوریتم را بدست آوریم.

T(n)=3^{logn}+O(n)

T(n)=O(n^{log3})=O(n^{1.59})

پس به اندازهٔ O(n^{1.59}) طول می‌کشد تا بتوانیم حاصل این ضرب را بدست آوریم.

### الگوریتم توم ـ کوک
**الگوریتم توم ـ کوک** که گاهی با نام **توم ـ ۳** شناخته می‌شود، ابتدا توسط اندری توم ارائه شد و سپس استفان کوک آن را به صورت شفاف‌تر در پایان‌نامه دکتری خود بیان کرد.الگوریتم توم ـ کوک انواع مختلفی دارد که الگوریتم توم ـ ۳ یکی از آن‌هاست. این الگوریتم تعمیم داده شدهٔ الگوریتم کاراتسوبا است. به‌طور دقیق‌تر الگوریتم کاراتسوبا حالت خاصی از الگوریتم توم ـ کوک است. پیچیدگی یک الگوریتم توم ـ k به صورت O(n^{log_k(2k-1)}  ) است.

## جستارهای وابسته
* الگوریتم کاراتسوبا
* الگوریتم تقسیم و حل
* تبدیل سریع فوریه

## منابع

رده:الگوریتم‌های محاسباتی رایانه
رده:ضرب (ریاضی)