<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های امیرحسین محسنی</title>
        <link>https://virgool.io/feed/@m_66394585</link>
        <description>من امیرحسین ام. برنامه نویس و توسعه دهنده نرم افزار هستم و علاقه مندم که موضوعاتی رو که خودم مطالعه میکنم با شما به اشتراک بگذارم.</description>
        <language>fa</language>
        <pubDate>2026-06-25 08:56:27</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/2780131/avatar/AwNfOT.jpg?height=120&amp;width=120</url>
            <title>امیرحسین محسنی</title>
            <link>https://virgool.io/@m_66394585</link>
        </image>

                    <item>
                <title>چرا هفتاد درصد فروشگاه های آنلاین هرگز به فروش نمیرسند؟</title>
                <link>https://virgool.io/@m_66394585/%DA%86%D8%B1%D8%A7-%D9%87%D9%81%D8%AA%D8%A7%D8%AF-%D8%AF%D8%B1%D8%B5%D8%AF-%D9%81%D8%B1%D9%88%D8%B4%DA%AF%D8%A7%D9%87-%D9%87%D8%A7%DB%8C-%D8%A2%D9%86%D9%84%D8%A7%DB%8C%D9%86-%D9%87%D8%B1%DA%AF%D8%B2-%D8%A8%D9%87-%D9%81%D8%B1%D9%88%D8%B4-%D9%86%D9%85%DB%8C%D8%B1%D8%B3%D9%86%D8%AF-qqfh4ejpkqh6</link>
                <description>همه ما بارها و بارها در طول روز به سایت های مختلفی سر میزنیم و این روز ها خیلی از خرید هایمان را به صورت اینترنتی انجام میدهیم، و این بین گاهی با خودمان میگوییم؛ عجب درآمدی دارند از سایت، اما خبر نداریم که پشت سر این سایت های موفقی که از آنها خرید میکنیم، قبرستانی پر از کسب و کار هایی است که سرمایه زیادی، برای راه اندازی سایت گذاشتند اما در نهایت هیچ درآمدی از آن کسب نکردند.چرا فروشگاه های آنلاین به فروش نمیرسند؟راه اندازی و مدیریت یک فروشگاه آنلاین نیاز به مهارت های مختلفی دارد، اینکه صرفا یک سایت فروشگاهی ایجاد شود به این معنا نیست که قرار است از فردای آن روز، مشتری ها وارد آن سایت شوند و خرید کنند. درست کار نکردن در هر بخشی میتواند باعث به نتیجه نرسیدن، کسب و کار آنلاین ما شود؛ در ادامه بعضی از دلایل شکست کسب و کار های آنلاین را بررسی میکنیم.چون ایده کسب و کار، اونقدر که فکر میکردیم خوب نبود.خیلی از کسب و کار ها، با تصور اینکه ایده ای که دارند، بسیار خاص و ویژه است در شروع سرمایه گذاری زیادی میکنند اما در نهایت به نتیجه چندانی نمیرسند. برای جلوگیری از این مشکل، روش های مختلفی برای تست و بررسی های ایده های کسب و کاری، وجود دارد.چون سایت زیبا و راحت نیست.خیلی اوقات یک سایت، نیاز مهمی را از مشتری برطرف میکند اما متاسفانه مشتری در نگاه اول حس خوبی از سایت نمیگیرد و از آن خارج میشود، بنابراین بسیار مهم است که سایت رابط کاربری خوبی داشته باشد و کاربرها را راضی نگه دارد.چون سایت باگ داره یا درست لود نمیشه.اگر سایت ما، به دلایل مختلف از دسترس خارج شود یا کند باشد، یا خطا داشته باشد یا… چند اشتباه کوچک، برای از دست دادن مشتریان کافی است، پس باید دقت زیادی، در کد نویسی بهینه، وجود داشته باشد که این خطرات، کسب و کار آنلاین ما را تهدید نکند. چون محتوای با کیفیت، تولید نکردیم.تولید محتوا، قلب کسب و کار های آنلاین است، نمیتوان انتظار داشت که یک سایت صرفا با ظاهر زیبا و بدون محتوا رشد کند، اگر سایت ما، حرفی برای گفتن نداشته باشد، هیچ کاربری به آن توجه نخواهد کرد.چون روی سئو کار نکردیم و سایت بازدید نداشت.عالی ترین کسب و کار اینترنتی، بدون گرفتن بازدید هیچ ارزشی ندارد، زمانی که سایت ما کامل شد و محتوای مناسب در آن قرار گرفت، وقت افزایش بازدید و گرفتن مخاطب است، باید از منابع مختلف برای جذب مخاطب استفاده کرد و موتور های جستجو، یکی از این منابع هستند.چون دیجیتال مارکتینگ بلد نبودیم.هدف اصلی ما از راه اندازی کسب و کار آنلاین، کسب در آمد است، پس عملا همه این مراحل مقدمه ای بود که بتوانیم کالا و خدمات خودمان را در اینترنت به فروش برسانیم، پس لازم است که حتما تکنیک های فروش در اینترنت را بشناسیم و بتوانیم مسیر مشتری مناسبی طراحی کنیم و کمپین های فروش مناسب ایجاد کنیم.برای راه اندازی یک فروشگاه آنلاین موفق چه کار هایی لازم است؟راه اندازی یک فروشگاه اینترنتی سود آور، نیازمند تخصص و مهارت در بخش های مختلفی است، در واقع باید تمام قطعات پازل وجود داشته باشد تا یک فروشگاه اینترنتی کامل شود و صرف داشتن یک قطعه به تنهایی کافی نیست.نتیجه گیریراه اندازی سایت، یک ایده عالی برای کسب درآمد است اما نیاز به مهارت های متعددی دارد و بر خلاف چیزی که یک عده ادعا میکنند، همه فروشگاه های اینترنتی موفق نمیشوند. اگر قصد دارید یک فروشگاه اینترنتی راه بیاندازید، پیشنهاد میکنم که حتما به تمام این مراحل توجه داشته باشید و به یاد داشته باشید که با داشتن فقط یکی از قطعات پازل نمیشود آن را تکمیل کرد.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Wed, 10 Jul 2024 18:59:29 +0330</pubDate>
            </item>
                    <item>
                <title>برنامه نویسی داینامیک؛ راه حل الگوریتم های پیچیده</title>
                <link>https://virgool.io/codenevis/%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D8%AF%D8%A7%DB%8C%D9%86%D8%A7%D9%85%DB%8C%DA%A9-%D8%B1%D8%A7%D9%87-%D8%AD%D9%84-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D9%87%D8%A7%DB%8C-%D9%BE%DB%8C%DA%86%DB%8C%D8%AF%D9%87-bfr8vznjqckw</link>
                <description>برنامه نویسی داینامیک، یک روش حل مسئله است که در علوم کامپیوتر، کاربرد های زیادی دارد. این روش برای حل مسائل بسیار پیچیده استفاده میشود، و روش کار آن، به این صورت است که ابتدا مسئله بزرگ تر را، به ریزمسئله های کوچک تر تبدیل میکند و آنها را حل میکند و پاسخ این ریزمسئله ها را، نگهداری میکند و از آن برای حل ریز مسائل بعدی و در نهایت مسئله نهایی استفاده میکند.برنامه نویسی داینامیک چیست؟برنامه نویسی داینامیک، روشی است که در آن سعی میکنیم مسئله بزرگ را، تبدیل به مسائل کوچک تر کنیم و آنها را حل کنیم، از کنار هم قرار دادن جواب ریز مسئله ها، به جواب مسئله های پیچیده تر میرسیم و در نهایت میتوانیم که مسئله نهایی را حل کنیم.چرا باید از برنامه نویسی داینامیک استفاده کنیم؟برنامه نویسی داینامیک، بسیار پر کاربرد است به دلیل اینکه، در حل مسائل دشوار و پیچیده، بسیار کمک میکند و در عین حال از سرعت بالایی برخوردار است، در این روش، منابع به روش درستی مدیریت میشود و به دلیل ذخیره سازی جواب ریز مسائل، از تکرار محاسبات، جلوگیری میشود.چطور یک الگوریتم با روش داینامیک بنویسیم؟برنامه نویسی داینامیک از دو قسمت بسیار مهم، تشکیل شده است؛ خرد کردن مسئله و ذخیره سازی جواب ها. در ابتدا باید ببینیم که ساده ترین شکل مسئله چیست و جواب آن را به دست بیاوریم و در هر مرحله، مسئله را یک قدم بزرگ تر میکنیم و از جواب های ذخیره شده قبلی، استفاده میکنیم تا مسئله جدید را حل کنیم و این روند تا جایی ادامه پیدا میکند که مسئله نهایی را حل کنیم.مثالی برای درک بهتردر مقاله قبلی با مسئله کوله پشتی، آشنا شدیم و در این مقاله میخواهیم که با روش داینامیک آن مسئله را حل کنیم. ما به عنوان یک سارق، وارد فروشگاه شده ایم و میخواهیم با ارزش ترین کالاهایی را، که میتوانیم در کوله پشتی مان جا بدهیم با خودمان برداریم، ظرفیت کوله پشتی محدود است و بسیار مهم است که بدانیم کدام کالاها را برداریم.کالاها این سه مورد است و کوله پشتی ما، فقط 4 کیلو گرم وزن را میتواند تحمل کند.در مرحله اول باید مسئله بزرگ را، به یک مسئله کوچک تر تبدیل کنیم، برای مثال اگر ما یک کوله پشتی داشتیم که فقط یک کیلوگرم را میتوانست تحمل کند، و فروشگاه هم فقط پاوربانک داشت، در این صورت بهترین کار این بود که همان پاوربانک را برداریم و در نهایت 2.5 میلیون سود میکردیم. حالا باید این جواب را ذخیره کنیم که در مراحل بعدی بتوانیم از آن استفاده کنیم، برای این کار از یک گرید استفاده میکنیم.مرحله بعدی این است که فرض کنیم کوله بزرگ تری میتوانیم داشته باشیم و همین مسئله را مجددا حل کنیم، بعد از این مرحله، جدول ما به صورت زیر خواهد بود.حالا فرض میکنیم که فروشگاه ما، یک کالای دیگر هم دارد و آن لپ تاپ است، لپ تاپ 4 کیلو گرم وزن دارد پس آن را فقط میتوانیم در کوله پشتی 4 کیلویی، قرار بدهیم اگر این کار بکنیم، ارزش نهایی کوله پشتی مان، 7 میلیون تومان خواهد بود و این نسبت به جواب قبلی که برای کوله پشتی 4 کیلویی داشتیم بهتر است، پس این کار را انجام میدهیم.حالا همین مسئله را، باید با این فرض حل کنیم که کالای اسپیکر هم در فروشگاه وجود دارد، اسپیکر 3 کیلو گرم وزن دارم، اگر بخواهیم کوله 3 کیلوگرمی را، با اسپیکر پر کنیم، 5 میلیون تومان سود میکنیم و این بهتر از جواب قبلی است پس این کار را انجام میدهیم.اگر بخواهیم اسپیکر را در کوله 4 کیلوگرمی قرار بدهیم، 1 کیلوگرم اضافه میماند که با توجه به جواب های قبلی بهترین کاری که میتوانی با 1 کیلوگرم انجام بدهیم این است که پاوربانک را برداریم که ارزش آن 2.5 میلیون است، در نتیجه مجموع ارزش کالاهایی که برداشتیم 7.5 میلیون تومان میشود که از جواب قبلی بهتر است. گرید ما در نهایت به شکل زیر خواهد بود.بهترین جواب، برای این مسئله این است که پاوربانک و اسپیکر را برداریم که مجموع قیمت آنها میشود 7.5 میلیون تومان.جمع بندیدر این مقاله، با روش برنامه نویسی داینامیک آشنا شدیم که از روش های پرکاربرد حل مسئله در علوم کامپیوتر است و در موضوعات مختلف استفاده میشود، البته باید توجه داشته باشیم که این مبحث، یک مبحث پیچیده است و طبیعتا مطالعه یک مقاله برای یادگیری کامل آن کافی نیست، اما سعی کردیم که در این مقاله، با مفاهیم کلی و طرز فکر برنامه نویسی داینامیک، آشنا شویم.امیدوارم مطالعه این مقاله برایتان مفید بوده باشد، خیلی ممنون میشم که نظرتون رو بهم بگید.اگر این مطلب برایتان مفید بود، پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده را دنبال کنید.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Tue, 30 Apr 2024 18:59:21 +0330</pubDate>
            </item>
                    <item>
                <title>الگوریتم حریصانه چیست و چرا باید از آن استفاده کنیم؟</title>
                <link>https://virgool.io/@m_66394585/%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D8%AD%D8%B1%DB%8C%D8%B5%D8%A7%D9%86%D9%87-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D8%B1%D8%A7-%D8%A8%D8%A7%DB%8C%D8%AF-%D8%A7%D8%B2-%D8%A2%D9%86-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%DA%A9%D9%86%DB%8C%D9%85-vztuwlwxeh0y</link>
                <description>فرض کنیم که ما یک پستچی هستیم و قرار است که از اداره پست شروع به حرکت کنیم و ده بسته پستی را، به ده مقصد مختلف ببریم، میخواهیم یک الگوریتم بنویسیم که به ما بگوید این بسته ها را با چه ترتیبی ببریم تا در کمترین زمان ممکن، همه بسته ها را برسانیم. اگر بخواهیم الگوریتمی بنویسیم که همه حالت ها را در نظر بگیرد و بهینه ترین حالت را پیدا کند، اجرا کردن این الگوریتم بسیار زمان بر میشود، در عوض میتوانیم از یک راه حل ساده تر، استفاده کنیم؛ در هر مرحله نزدیک ترین مقصد را پیدا میکنیم و بسته مربوط به آن را تحویل میدهیم، شاید در نهایت این روش بهینه ترین مسیر را به ما ندهد اما باز هم تا حد خوبی بهینه خواهد بود، به این روش الگوریتم حریصانه میگوییم.الگوریتم حریصانه چیست؟الگوریتم حریصانه، یک استراتژی حل مسئله است که زمانی به سراغ آن میرویم که میخواهیم الگوریتم های بسیار سریع بنویسیم، البته باید این نکته را هم در نظر بگیریم که الگوریتم های حریصانه همیشه بهترین جواب ممکن را به ما نمیدهند اما با این حال، راه حل حریصانه تا حد زیادی کارآمد است.طرز فکر حریصانه، به این صورت است که ما در هر مرحله بهترین حرکت را انتخاب میکنیم و این باعث میشود که راه حل مناسبی برای کل مسئله داشته باشیم، در مثالی که ابتدای این مطلب به آن اشاره کردیم، محاسبه بهترین مسیر بسیار زمان بر است و ما میخواهیم الگوریتم سریع تری داشته باشیم پس به سراغ الگوریتم حریصانه میرویم، به این صورت که در هر مرحله، نزدیک ترین مقصد را انتخاب میکنیم و در نهایت به یک راه حل نسبتا خوب میرسیم.چرا از الگوریتم های حریصانه استفاده میکنیم؟مهم ترین فایده الگوریتم های حریصانه، سرعت بالای ای الگوریتم ها در حل مسئله است، مخصوصا زمانی که ما با مسائلی روبرو میشویم که بسیار پیچیده و زمان بر هستند، اما از طرفی باید این مسئله را هم باید در نظر بگیریم که الگوریتم های حریصانه، همیشه دقیق ترین جواب را به ما نمیدهند اما جوابی که میدهند تا حد زیادی کارآمد است. ما زمانی سراغ الگوریتم های حریصانه میرویم که سرعت اجرای نرم افزار، اولویت بیشتری نسبت به دقت آن دارد، در واقع ما میپذیریم که جواب نسبتا درست را کافی بدانیم در ازای اینکه نرم افزارمان چندین برابر سریعتر شود.الگوریتم های حریصانه چطور کار میکنند؟در واقع پیاده سازی الگوریتم های حریصانه بسیار ساده است، باید در هر مرحله بهترین جواب را پیدا کنیم، برای این کار ابتدا باید بدانیم که هدف الگوریتمی که میخواهیم بنویسیم چیست؟ بعد از آن باید معیاری برای آن در نظر بگیریم و در هر مرحله، گزینه ای را انتخاب کنیم که ما را به آن معیار نزدیک تر میکند. با بررسی یک مثال، بیشتر متوجه سادگی این الگوریتم ها میشویم.بررسی مثالی برای درک بهترفرض کنیم ما یک سارق هستیم و میخواهیم از یک فروشگاه دزدی کنیم و یک کوله پشتی همراه خودمان داریم، اما ظرفیت این کوله پشتی محدود است و فقط تا 4 کیلوگرم وزن را میتواند تحمل کند، ما باید هر چه سریع تر تصمیم بگیریم که چه چیز های را برداریم که بیشترین ارزش ممکن را داشته باشد اما از طرفی هم نباید بیش از حد زمان را هدر بدهیم و درگیر محاسبه وزن ها و قیمت ها شویم، به دلیل اینکه زمانی که داریم بسیار کم است، در این شرایط بهترین راه این است که به سراغ الگوریتم حریصانه برویم. هدف ما در این مسئله چیست؟ این است که با ارزش ترین کالا ها را برداریم پس اگر بخواهیم حریصانه انتخاب کنیم، باید در هر مرحله، گران قیمت ترین کالای فروشگاه را، برداریم تا زمانی که کوله پشتی مان دیگر جایی برای چیز دیگری نداشته باشد. اما آیا این کار همیشه بهترین جواب ممکن را به ما میدهد؟فرض کنیم در فروشگاه، سه نوع کالا وجود دارد، لپ تاپ، پاور بانک، اسپیکر.اگر بخواهیم طبق الگوریتم حریصانه پیش برویم، در ابتدا لپ تاپ را بر میداریم چون گران قیمت ترین کالای فروشگاه است و پس از آن دیگر جایی برای کالای دیگری نداریم و در نهایت 7 میلیون تومان برداشته ایم، در صورتی که اگر پاور بانک و اسپیکر را برمیداشتیم سود بیشتری میکردیم. در نتیجه الگوریتم های حریصانه همیشه بهترین جواب را به ما نمیدهند اما جواب تقریبا درستی میدهند و با توجه به اینکه بسیار سریع تر هستند در خیلی از موارد کاربرد دارند.جمع بندیدر این مقاله با الگوریتم های حریصانه آشنا شدیم و یاد گرفتیم چطور از این استراتژی، برای حل مسائل استفاده کنیم. الگوریتم های حریصانه بسیار کاربردی هستند و در هوش مصنوعی و یادگیری ماشین و همچین کار با شبکه های کامپیوتری، استفاده میشوند.اگر این مطلب برایتان مفید بود، پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده را دنبال کنید.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Sat, 06 Apr 2024 11:12:22 +0330</pubDate>
            </item>
                    <item>
                <title>الگوریتم پیدا کردن کوتاه ترین مسیر در گراف غیر هم وزن</title>
                <link>https://virgool.io/codenevis/%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D9%BE%DB%8C%D8%AF%D8%A7-%DA%A9%D8%B1%D8%AF%D9%86-%DA%A9%D9%88%D8%AA%D8%A7%D9%87-%D8%AA%D8%B1%DB%8C%D9%86-%D9%85%D8%B3%DB%8C%D8%B1-%D8%AF%D8%B1-%DA%AF%D8%B1%D8%A7%D9%81-%D8%BA%DB%8C%D8%B1-%D9%87%D9%85-%D9%88%D8%B2%D9%86-pp7bpx26hhn3</link>
                <description>در مقاله قبلی با الگوریتم جستجوی سطح اول آشنا شدیم که با کمک میکرد در یک گراف هم وزن مسیریابی کنیم، اما جستجوی سطح اول، در گراف های غیر هم وزن کاربردی ندارد. برای مثال اگر بخواهیم از یک نقطه از نقشه، به نقطه دیگری سفر کنیم، طول خیابان ها و جاده ها، یکسان نخواهد بود، پس ما به یک الگوریتم مسیریابی دیگر نیاز داریم که برای گراف های غیر هم وزن هم کار کند.الگوریتم دیکسترا Dijkstra چیست و چه کاربردی دارد؟الگوریتم دیکسترا، برای پیدا کردن کوتاه ترین مسیر استفاده میشود و در گراف های غیر هم وزن هم کاربرد دارد، این الگوریتم، یکی از الگوریتم های پایه ای در علوم کامپیوتر است و نام گذاری آن، به نام دانشمند هلندی است که این الگوریتم را برای اولین بار، ارائه داد.هرچند این الگوریتم، برای پیدا کردن کوتاه ترین مسیر در گراف استفاده میشود، اما به این معنی نیست که فقط در نرم افزار های مسیریابی کاربرد دارد، این الگوریتم در شبکه و هوش مصنوعی هم کاربرد فراوانی دارد.الگوریتم دیکسترا چطور کار میکند؟الگوریتم دیکسترا، از چند مرحله بسیار ساده تشکیل شده است، در شروع کار، ما باید یک جدول طراحی کنیم و مدت زمانی که برای رسیدن به هر راس از گراف ، لازم است را در آن مینویسیم، در ابتدا که هنوز این اعداد محاسبه نشده برای راس مبدا، عدد صفر را قرار میدهیم و برای بقیه راس ها، بینهایت میگذاریم، سپس باید مراحل زیر را، تا جایی تکرار کنیم که همه راس ها را محاسبه کنیم.پیدا کردن نزدیک ترین راس؛ نزدیک ترین راسی که در حال حاضر، میتوانیم به آنجا برویم را پیدا میکنیم.از این راس به کدام راس ها میتوان رفت؟ اعدادی که در جدول، برای آن راس ها در نظر گرفتیم باید به روز شود.همین کار را تا جایی تکرار میکنیم که همه راس ها را، محاسبه کنیم و بتوانیم مسیر نهایی را محاسبه کنیم.در شروع کار نزدیک ترین نقطه ای که میتوانیم برویم، همان نقطه مبدا است و باید اعداد مربوط به همسایه های آن را تغییر دهیم، همچنین باید توجه داشته باشیم که این عملیات را برای هر راس، فقط یک بار انجام بدهیم.مثالی برای درک بهترما میخواهیم با استفاده از الگوریتم دیکسترا، سریع ترین مسیر، بین نقطه شروع و پایان، در نقشه بالا را پیدا کنیم، مرحله اول این است که همه راس ها را، در یک جدول قرار دهیم تا بتوانیم زمان رسیدن به هر یک را، محاسبه کنیم.در ابتدا که اعداد را، محاسبه نکرده ایم عدد بی نهایت را قرار میدهیم و فقط نقطه شروع را صفر قرار میدهیم، سپس شروع میکنیم به تکرار سه مرحله که در بالا اشاره کردیم. مرحله اول پیدا کردن نزدیک ترین راس؛ در حال حاضر نزدیک ترین راس همان نقطه شروع است، مرحله دوم این است که اعداد مربوط به همسایه های این راس، را تغییر دهیم، از نقطه شروع متیوانیم با دو دقیقه زمان، به نقطه B برسیم و با 6 دقیقه زمان به نقطه A برسیم، پس جدول ما به صورت زیر خواهد شد.حالا باید همین مراحل را، دوباره تکرار کنیم این باز نزدیک ترین راس، نقطه B خواهد بود، از این نقطه میتوانیم به نقطه A و نقطه پایان، سفر کنیم، برای رسیدن از نقطه B به نقطه A سه دقیقه زمان لازم است، و دو دقیقه زمان هم برای رسیدن به نقطه B، پس با استفاده از این راه جدید ما میتوانیم در عرض پنج دقیقه به نقطه A، برسیم. جدول جدید پس محاسبه اطلاعات مربوط به نقطه B، به صورت زیر خواهد شد.مجددا باید مراحل را تکرار کنیم، نزدیک ترین راسی که میتوانیم به آن برویم، نقطه A است (نقطه شروع و نقطه B، قبلا بررسی شده است). از نقطه A، میتوانیم با صرف کردن یک دقیقه به نقطه پایان برسیم، بنابرین ما میتوانیم در مجموع با شش دقیقه زمان، از نقطه شروع به نقطه پایان برسیم و مسیر نهایی به این صورت خواهد بود.مقایسه الگوریتم دیکسترا و BFSدر این مقاله با الگوریتم دیکسترا، آشنا شدیم و در مقاله قبلی با الگوریتم دیگری به نام &quot;الگوریتم جستجوی سطح اول&quot; آشنا شده بودیم که از آن هم برای مسیریابی استفاده میکردیم، اما تفاوت این دو الگوریتم در کجاست؟ یکی از مهم ترین تفاوت ها این است که الگوریتم دیکسترا، برای گراف های غیر هم وزن هم کاربرد دارد، در صورتی که، جستجوی سطح اول، فقط برای گراف های هم وزن کاربرد دارد، همچنین الگوریتم دیکسترا سرعت بیشتری هم نسبت به الگوریتم جستجوی سطح اول دارد.در مقابل الگوریتم جستجوی سطح اول، ساده تر است و به راحتی میتوان آن را پیاده سازی کرد و کاربرد آن محدود به الگوریتم های مسیریابی نمیشود و در مواردی دیگر مانند جستجو در گراف استفاده میشود.جمع بندیدر این مقاله با الگوریتم دیکسترا، آشنا شدیم و یاد گرفتیم چطور از آن برای مسیریابی در گراف غیر هم وزن استفاده کنیم اما باید حتما به این نکته توجه داشته باشیم که کاربرد الگوریتم دیکسترا، به نرم افزار های مسیریابی محدود نمیشود و در هوش مصنوعی، شبکه های اجتماعی و هر جای دیگری که با گراف سر و کار داشته باشیم، میتواند استفاده شود.اگر این مطلب برایتان مفید بود، پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده را دنبال کنید.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Sun, 17 Mar 2024 22:03:59 +0330</pubDate>
            </item>
                    <item>
                <title>چطور یک الگوریتم مسیریابی بنویسیم؟</title>
                <link>https://virgool.io/codenevis/%DA%86%D8%B7%D9%88%D8%B1-%DB%8C%DA%A9-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D9%85%D8%B3%DB%8C%D8%B1%DB%8C%D8%A7%D8%A8%DB%8C-%D8%A8%D9%86%D9%88%DB%8C%D8%B3%DB%8C%D9%85-ymrj0eb02xeh</link>
                <description>چطور سریع ترین مسیر را پیدا کنیم؟ در این مقاله می خواهیم یک الگوریتم مسیریابی، برای خطوط مترو بنویسیم. فرض میکنیم که فاصله هر ایستگاه، با ایستگاه بعدی یکسان است، حالا میخواهیم که الگوریتمی بنویسیم که ایستگاه مبدا و مقصد را به آن بدهیم و نزدیک ترین مسیر بین این دو ایستگاه را به ما دهد. منظورمان از نزدیک ترین مسیر، مسیری است که کمترین تعداد ایستگاه را داشته باشد. برای اینکه این الگوریتم را بنویسیم، اول باید با یک ساختار داده بسیار مهم و کاربردی، آشنا شویم؛ گراف!گراف چیست؟گراف، یک نوع ساختار داده است که برای نشان دادن ارتباطات بین داده ها استفاده میشود، هر گراف از تعدادی راس و تعدادی یال تشکیل میشود. راس که به آن گره هم گفته میشود، نقطه هایی هستند که در گراف نشان دهنده اشیاء هستند و یال به خطوطی گفته میشود که این نقاط را به یکدیگر متصل میکند.در چه مواردی از گراف استفاده میکنیم؟به طور کلی ما در هرجایی که بخواهیم ارتباط بین اشیاء را نشان دهیم از گراف استفاده میکنیم، برای مثال در شبکه های اجتماعی برای نشان دادن ارتباط بین افراد از گراف استفاده میشود، یا در یک نقشه برای نشان دادن مسیر های بین شهر ها. ما میخواهیم یک الگوریتم مسیریابی، برای خطوط مترو بنویسیم و برای نگه داشتن اطلاعات ایستگاه ها و ارتباط آن ها از گراف استفاده میکنیم.الگوریتم جستجوی سطح اول (BFS) چیست؟الگوریتم جستجوی سطح اول، یک الگوریتم است که برای پیدا کردن کوتاه ترین مسیر بین دو راس در یک گراف استفاده میشود. این الگوریتم، از راسی که به عنوان مبدا در نظر گرفتیم شروع میکند و تمام رئوس را به ترتیب نزدیک بودن بررسی میکند تا زمانی به مقصد برسد و با این روش کوتاه ترین مسیر را محاسبه میکند.جستجوی سطح اول چطور کار میکند؟الگوریتم جستجوی سطح اول، بسیار ساده است، برای پیاده سازی این الگوریتم ما نیاز به یک صف داریم. صف یک نوع ساختار داده است که کاملا مشابه همان مفهومی است که در دنیای واقعی دارد، داده ها یکی یکی، وارد صف میشوند و به همان ترتیبی که وارد شدند خارج می‌شوند.برای پیاده سازی این الگوریتم، ما نیاز به یک صف داریم که در شروع کار فقط راس مبدا را در آن قرار میدهیم، سپس سه مرحله زیر را مدام تکرار میکنیم تا به مقصد برسیم.اولین داده را، از صف بردار.آیا به مقصد رسیدیم؟اگر به مقصد نرسیدیم، همه راس های مجاور این راس را که قبلا بررسی نشده در صف قرار بده.این سه مرحله تا جایی تکرار میشود که به مقصد برسیم.مثالی برای درک بهترفرض کنیم ما میخواهیم با استفاده از مترو تهران، از ایستگاه شهید بهشتی به ایستگاه میدان ولیعصر برویم و میخواهیم از الگوریتم جستجوی سطح اول برای مسیریابی استفاده کنیم. ابتدا ایستگاه شهید بهشتی را در صف قرار میدهیم و شروع میکنیم به انجام مراحل.اولین داده را، از صف بردار : اولین داده ای که در صف قرار دارد، همان ایستگاه شهید بهشتی است.آیا به مقصد رسیده ایم؟ : مقصد ما، ایستگاه میدان ولیعصر بود، پس فعلا باید ادامه بدهیم.همه راس های مجاور را در صف قرار بده : چهار ایستگاه در همسایگی ایستگاه شهید بهشتی وجود دارد و ما باید این چهار ایستگاه را در صف قرار دهیم. صف جدید به این صورت خواهد بود [مصلی امام خمینی، میرزای شیرازی، شهید مفتح، سهروردی]همین فرایند را باید تکرار کنیم تا جایی که به ایستگاه مقصد برسیم، اما باید دقت داشته باشیم که ایستگاه های تکراری را به صف اضافه نکنیم، برای مثال زمانی که ما ایستگاه مصلی را بررسی میکنیم و به مرحله سوم میرسیم، باید همسایه های ایستگاه مصلی را به صف اضافه کنیم اما باید دقت داشته باشیم که ایستگاه بهشتی را مجددا به صف اضافه نکنیم چون قبلا یک بار بررسی شده است. برای جلوگیری از این اشتباه، باید ایستگاه های بررسی شده را در یک آرایه ذخیره کنیم.دو نکته قابل توجهجستجوی سطح اول، فقط با این فرض درست کار میکند که فاصله همه ایستگاه ها، با هم برابر باشد. به عبارتی فقط برای گراف های هم وزن کار میکند، برای مسیریابی در گراف غیر هم وزن باید از الگوریتم دیگری استفاده کنیم که در مقالات بعدی با آن آشنا خواهیم شد.نکته دیگری که باید درباره الگوریتم جستجوی سطح اول بدانیم، این است که برای گراف های بزرگ، عملکرد خوبی ندارد، به دلیل اینکه ما باید تمام رئوس گراف را ذخیره کنیم و این ممکن است باعث پر شدن حافظه بشود.جمع بندیدر ابتدای این مقاله با مفهوم گراف، آشنا شدیم که یکی از پر کاربرد ترین ساختار های داده است و به طور خاص برای نشان دادن ارتباطات بین داده ها استفاده میشود، و همچنین با الگوریتم جستجوی سطح اول، آشنا شدیم و یاد گرفتیم که چطور کار میکند و چه کاربرد هایی دارد. جستجوی سطح اول در مواردی غیر از مسیریابی هم استفاده میشود، برای مثال برای پیدا کردن یک داده در یک شبکه.اگر این مطلب برایتان مفید بود، پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده را دنبال کنید.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Tue, 12 Mar 2024 21:05:41 +0330</pubDate>
            </item>
                    <item>
                <title>جدول هش یا Hash table چیست و چه کاربرد هایی دارد؟</title>
                <link>https://virgool.io/codenevis/%D8%AC%D8%AF%D9%88%D9%84-%D9%87%D8%B4-%DB%8C%D8%A7-hash-table-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D9%87-%DA%A9%D8%A7%D8%B1%D8%A8%D8%B1%D8%AF-%D9%87%D8%A7%DB%8C%DB%8C-%D8%AF%D8%A7%D8%B1%D8%AF-zfvdil8sqn1b</link>
                <description>تا کنون با دو ساختار داده مهم برای نگهداری از مجموعه ای از داده ها، آشنا شده ایم؛ آرایه و لیست پیوندی. در مقالات قبلی سرعت این دو ساختار داده در گرفتن و اضافه کردن دیتا را بررسی کردیم. در این مقاله میخواهیم درباره یک ساختار داده دیگر صحبت کنیم که هم در اضافه کردن دیتا خیلی سریع است و هم در خواندن آن؛ Hash table یا جدول هش!جدول هش یا Hash Table چیست؟هش تیبل، یکی از ساختار داده های اساسی است که استفاده های زیادی در توسعه نرم افزار دارد، یکی از دلایل اصلی محبوبیت هش تیبل، سرعت بالای آن در ثبت و خواندن داده هاست، پیچیدگی زمانی هش تیبل برای ثبت و خواندن داده به صورت O(1) است و این نشان میدهید که هش تیبل، یکی از بهترین گزینه ها برای زمان هاییست که با حجم زیادی از داده ها سر و کار داشته باشیم. هش تیبل از ترکیب آرایه و تابع هش برای مدیریت داده ها استفاده میکند که در ادامه درباره نحوه کار، بیشتر صحبت خواهیم کرد.چرا از Hash Table استفاده میکنیم؟همانطور که گفتیم هش تیبل از ساختار داده های پر کاربردی است که در موارد زیادی استفاده میشود، اما علت این محبوبیت چیست؟ در ادامه به چند مورد از مهم ترین مزایای هش تیبل اشاره میکنیم1.      سرعت بالا در درج و حذف داده هایکی از مشکلاتی ما هنگام استفاده از آرایه ها داشتیم، این بود که هنگام درج و حذف دیتا، مجبور میشدیم که داده های دیگر را جابجا کنیم و این عملیات، بسیار زمان بر بود. اما در ساختار داده هش تیبل، این فرایند بهینه شده و دیگر نیازی به جابجایی داده ها نیست.2.      جستجوی سریع بین داده هاجستجوی بین داده ها در هش تیبل، بسیار سریع اتفاق می افتد، در واقع ساختار داده هش تیبل، داده ها را با استفاده از تابع هش به نقاط مشخصی از آرایه میفرستد، در نتیجه در هنگام جستجو کافیست مجددا با استفاده از تابع هش، همان نقطه را پیدا کند، بدون اینکه نیاز باشد داده های دیگر را بررسی کند. در ادامه بیشتر درباره نحوه کار هش تیبل صحبت میکنیم و این مطلب واضح تر خواهد شد.3.      استفاده در دیکشنری ها و دیتابیس هاهش تیبل، به دلیل استفاده بهینه از فضا و مدیریت داده ها با سرعت بالا، در دیتابیس ها کاربرد زیادی دارد. ایندکس گزاری در دیتابیس ها از طریق هش تیبل انجام میشود، و این امکان را به ما میدهد تا عملیات ثبت، حذف و جستجو را بسیار سریع تر انجام دهیم.4.      استفاده برای رمزگزاری کردن داده ها و بالا بردن امنیتیکی از کاربرد های مهم تابع هش، رمز گزاری کردن داده هاست، برای مثال زمانی که بخواهیم رمز عبور کاربران را دیتابیس ذخیره کنیم، ابتدا آن را با استفاده از تابع هش رمزنگاری میکنیم و سپس در دیتابیس ذخیره میکنیم. در این صورت ادمین دیتابیس یا هر شخص دیگری نمیتواند با بررسی دیتابیس رمز عبور کاربران را ببیند.جدول هش چطور کار میکند؟همانطور که گفتیم هش تیبل با استفاده از ترکیب تابع هش و آرایه کار میکند، در واقع هش تیبل، یک آرایه است که بهینه شده است. کنترل اینکه داده ها در کدام قسمت آرایه ذخیره شوند با تابع هش است.تابع هش چیست؟تابع هش، یک الگوریتم محاسباتی است که یک داده را به عنوان ورودی میگیرد و یک عدد(کد هش) را به عنوان خروجی برمیگرداند. تابع هش باید این دو ویژگی را داشته باشد:به ازای ورودی یکسان، خروجی یکسان برگرداند؛ اگر ما یک داده را با استفاده از تابع هش تبدیل به یک عدد کنیم، باید هر بار که آن داده را در زمان های دیگر به تابع دادیم، باز هم همان عدد را به ما بدهد، در غیر این صورت تابع هش، هیچ کاربردی ندارد.ورودی های متفاوت را، به اعداد متفاوتی تبدیل کند؛ برای مثال اگر تابع ما به ازای تمام ورودی ها، عدد 1 را برگرداند چه فایده ای میتواند داشته باشد؟پس تابع هش، تابعی است که داده را تبدیل به یک عدد میکند و این دو ویژگی را دارد.آرایه هش چیست؟آرایه هش، آرایه ای است که دیتای هش تیبل در آن ذخیره میشود، اندازه این آرایه ثابت است و اینکه هر داده در کدام خانه قرار بگیرد توسط تابع هش تعیین میشود. یعنی ابتدا داده را به تابع هش میدهیم و یک عدد از آن میگیریم، آن عدد نشان میدهد که آن داده در کدام خانه از آرایه ذخیره خواهد شد. با بررسی یک مثال، این مسئله واضح تر میشود.بررسی مثالی از نحوه کار هش تیبلفرض کنیم ما میخواهیم یک لیست قیمت از محصولات فروشگاه، درست کنیم و میخواهیم برای این کار از هش تیبل، استفاده کنیم. در ابتدا باید یک آرایه خالی با تعداد خانه های کافی بسازیم، نام اولین محصول فروشگاه را به تابع هش میدهیم، برای مثال اولین محصول &quot;کلاه پشمی&quot; است، تابع هش به ما در ازای این محصول یک عدد میدهد، به عنوان مثال 274. ما اطلاعات محصول کلاه پشمی را در خانه 274 از آرایه ذخیره میکنیم، همین کار را برای همه محصولات دیگر انجام میدهیم، &quot;کاپشن چرمی&quot; به خانه 583 و &quot;کفش ورزشی&quot; به خانه 394 میرود. هر گاه بخواهیم یک محصول جدید به لیست محصولات فروشگاه اضافه کنیم ابتدا، نام محصول را به تابع هش میدهیم و اطلاعات محصول را در خانه ای که تابع هش به ما بگوید، ذخیره میکنیم.جستجوی محصولات در لیست هم بسیار سریع خواهد بود، کافیست نام محصول را به تابع هش بدهیم و مجددا عددی که محل ذخیره سازی اطلاعات محصول را نشان میدهد، به دست بیاوریم. همانطور که گفتیم تابع هش همیشه برای ورودی یکسان، خروجی یکسان خواهد داشت، پس هرگاه، کلاه پشمی را به تابع هش خودمان بدهیم، عدد 274 را به ما خواهد گفت.رفع تداخل هادر تعریف تابع هش گفتیم که برای ورودی های متفاوت، خروجی های متفاوت میدهد. این بهترین حالت پیاده سازی یک تابع هش است اما گاهی پیش میاید که تابع هش، دو ورودی را به یک عدد یکسان تبدیل کند. برای مثال ما کلاه پشمی را به تابع هش، دادیم و عدد 274 را گرفتیم، حالا میخواهیم محصول جدیدمان را به لیست اضافه کنیم، محصول جدید &quot;عینک آفتابی&quot; است، اما زمانی که عینک آفتابی را به تابع هش میدهیم باز هم عدد 274 را به ما برمیگرداند، در چنین موقعیتی باید چه کار کنیم؟ راه حل بسیار ساده است، ما از لیست پیوندی استفاده میکنیم. اطلاعات محصول جدید را در هر جایی از حافظه ذخیره میکنیم و آدرس آن را در خانه 274، در آرایه قبلی قرار میدهیم.جمع بندیهش تیبل به دلیل سرعت بالا در ثبت و حذف داده ها و همچنین بازخوانی داده ها، یکی از مهم ترین ساختار های داده در علوم کامپیوتر است. هش تیبل در طراحی دیتابیس ها، کاربرد گسترده ای دارد. هرچند ما به عنوان برنامه نویس، به احتمال زیاد نیازی به پیاده سازی هش تیبل نخواهیم داشت، اما آشنایی با آن و نحوه عملکردش، از این جهت مهم است که بتوانیم به بهترین و مفیدترین شکل از دیتابیس ها، استفاده کنیم.اگر این مطلب برایتان مفید بود، پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده را دنبال کنید.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Fri, 08 Mar 2024 00:04:52 +0330</pubDate>
            </item>
                    <item>
                <title>استراتژی تقسیم و حل، چه کمکی در طراحی الگوریتم میکند؟</title>
                <link>https://virgool.io/@m_66394585/%D8%A7%D8%B3%D8%AA%D8%B1%D8%A7%D8%AA%DA%98%DB%8C-%D8%AA%D9%82%D8%B3%DB%8C%D9%85-%D9%88-%D8%AD%D9%84-%DA%86%D9%87-%DA%A9%D9%85%DA%A9%DB%8C-%D8%AF%D8%B1-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D9%85%DB%8C%DA%A9%D9%86%D8%AF-j9a7rz9f2zsx</link>
                <description>گاهی اوقات، با مسئله ای روبرو میشویم که به قدری پیچیده به نظر میرسد که هیچ راه حلی برای آن به ذهن مان نمیرسد. در اینچنین موقعیت هایی معمولا باید از استراتژی تقسیم و حل استفاده کنیم. استراتژی تقسیم و حل به ما کمک میکند که مسائل بزرگ را تبدیل به مسائل کوچک تر کنیم و بعد آنها را حل کنیم.استراتژی تقسیم و حل چیست؟استراتژی تقسیم و حل، یک الگوریتم نیست که بتوانیم آن را برای حل مسئله مان، پیاده سازی کنیم، تقسیم و حل یک طرز فکر است که ما کمک میکند مسائل پیچیده را بهتر تحلیل کنیم. اگر بخواهیم به طور خلاصه بگوییم استراتژی تقسیم و حل، از دو مرحله تشکیل شده است، در مرحله اول باید بفهمیم که ساده ترین حالت مسئله چیست؟ فرض کنید میخواهیم الگوریتمی بنویسیم که یک لیست از اعداد بگیرد و حاصل ضرب آنها را برای ما حساب کند. ساده ترین حالت این مسئله چیست؟ ساده ترین حالت این است که لیست ما فقط یک عدد داشته باشد. در این صورت همان عدد، جواب مسئله خواهد بود.مرحله دوم این است که بفهمیم چطور مسئله را خرد کنیم تا جایی که یه ساده ترین حالت برسیم؟ برگردیم به مثال قبلی. اگر لیست ما بیشتر از یک عدد داشت چطور آن را خرد کنیم؟ کافیست یک عدد از مجموعه برداریم و آن را در حاصل ضرب بقیه اعداد ضرب کنیم. مسئله ما یک مرحله ساده تر شد، حالا کافیست حاصل ضرب مجموعه کوچک تر را حساب کنیم. و همین روش را ادامه میدهیم تا جایی که به ساده ترین حالت مسئله برسیم یعنی جایی که لیست ما فقط یک عدد داشته باشد.در ادامه مطلب، مثال های کاربردی تری از استراتژی تقسیم و حل را بررسی میکنیم.چرا از روش تقسیم و حل استفاده میکنیم؟روش تقسیم و حل به ما این امکان را میدهد که مسائل پیچیده را به ریزمسئله های کوچک تر تقسیم کنیم و سپس آنها را حل کنیم، این روش مزایای زیادی برای ما دارد که در ادامه به آنها اشاره میکنیم.1.      ساده شدن مسئلهمهم ترین ویژگی این روش، این است که میتواند مسائل پیچیده را ساده تر کند، در نتیجه طراحی الگوریتم و پیاده سازی آن الگوریتم در کد، به مراتب ساده تر خواهد شد.2.      خوانا تر شدن کدنویسیبا تقسیم مسئله به مسائل کوچک تر، کد برنامه قابل فهم تر و خوانا تر خواهد شد، به دلیل اینکه هر بخشی از کد، در واقع یک مسئله کوچک را حل میکند و به سادگی قابل پیاده سازی است. خوانایی کد باعث میشود که اگر برنامه نویس دیگری بخواهد کدهای ما را بخواند، به راحتی متوجه آن شود.3.      موازی اجرا کردن بخش های مختلفبا تقسیم کردن مسئله به بخش های کوچک، میتوانیم بخش های کوچک مسئله را به طور موازی اجرا کنیم، این کار باعث میشود که بتوانیم از تمام ظرفیت سیستم به صورت بهینه استفاده کنیم، در نتیجه الگوریتم با سرعت بیشتری اجرا خواهد شد.چطور یک مسئله را به مسئله های کوچک تر تقسیم کنیم؟در ابتدای مقاله توضیح دادیم که روش تقسیم و حل از دو مرحله تشکیل شده است، پیدا کردن ساده ترین حالت و خرد کردن مسئله تا جایی که به ساده ترین حالت برسد. در این قسمت میخواهیم با بررسی دو مثال کاربردی، این مطلب را بهتر درک کنیم.حل کردن برج هانوی با استفاده از استراتژی تقسیم و حلفرض کنیم که میخواهیم الگوریتمی بنویسیم تا برج هانوی را، با هر تعداد دیسکی حل کند، به نظر میرسد که این مسئله کمی پیچیده است، پس بهتر است که از استراتژی تقسیم و حل، استفاده کنیم. ساده ترین حالت برج هانوی چیست؟ ساده ترین حالت این است که ما فقط بخواهیم یک دیسک را جابجا کنیم، در این صورت مستقیما آن را به ستون هدف میبریم.مرحله دوم این است که بفهمیم چطور حالت های پیچیده تر را خرد کنیم تا به حالت پایه برسیم؟ فرض کنیم بخواهیم 5 دیسک را جابجا کنیم، در این صورت ابتدا باید چهار دیسک بالایی را، به ستون وسط بیاوریم، دیسک پنجم را به ستون هدف بیاوریم و بعد از آن مجددا چهار دیسک دیگر را به ستون هدف بیاوریم. در واقع با این کار ما مسئله را یک مرحله کوچک تر کردیم و الان کافیست بدانیم که چطور 4 دیسک را جابجا کنیم، همین کار را باید تکرار کنیم تا جایی که به ساده ترین حالت برسیم. کد این الگوریتم در زبان C# به صورت زیر خواهد بود.مرتب سازی آرایه با روش تقسیم و حل (Quick Sort)یکی از الگوریتم های معروف مرتب سازی، Quick Sort است که از استراتژی تقسیم و حل استفاده میکند. برای اینکه یک آرایه را از روش تقسیم و حل مرتب کنیم، اول باید بدانیم که ساده ترین حالت آن چیست؟ ساده ترین حالت برای مرتب سازی یک آرایه، این است که فقط یک عضو داشته باشد، اگر تعداد اعضای آرایه، بیشتر باشد باید مسئله را ساده تر کنیم. روش ساده کردن، به این صورت است که یکی از اعضا را به صورت اتفاقی انتخاب میکنیم، سپس اعضای کوچک تر آن را در یک آرایه و اعضای بزرگتر را در یک آرایه دیگر قرار میدهیم و دو آرایه کوچکتر را مرتب میکنیم. بعد از این که دو آرایه کوچکتر را مرتب کردیم، آن عضو انتخاب شده را بین آن دو قرار میدهیم. این روش مرتب سازی در حالت میانگین از بقیه الگوریتم های مرتب سازی سریع تر خواهد بود.نتیجه گیریاستراتژی تقسیم و حل، یک ابزار قدرتمند برای تجزیه و تحلیل کردن مسائل پیچیده است که میتوانیم به وسیله آن الگوریتم های بهتری طراحی کنیم. استراتژی تقسیم و حل، سرعت الگوریتم ما را هم بالاتر خواهد برد، به دلیل اینکه به ما امکان اجرای موازی بخش های نرم افزار را میدهد.در این مقاله ما با استراتژی تقسیم و حل، آشنا شدیم اما باید بدانیم که استفاده کردن از آن در حل مسائل نیاز به تمرین و کسب مهارت دارد.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.اگر این مطلب برایتان مفید بود، پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده را دنبال کنید.منبع : سری مقالات الگوریتم و ساختمان داده در سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Fri, 01 Mar 2024 23:07:22 +0330</pubDate>
            </item>
                    <item>
                <title>توابع بازگشتی و استفاده آنها در طراحی الگوریتم</title>
                <link>https://virgool.io/@m_66394585/%D8%AA%D9%88%D8%A7%D8%A8%D8%B9-%D8%A8%D8%A7%D8%B2%DA%AF%D8%B4%D8%AA%DB%8C-%D9%88-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A2%D9%86%D9%87%D8%A7-%D8%AF%D8%B1-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-tzhtywhvoiu9</link>
                <description>در این مطلب میخواهیم درباره یکی از جذاب ترین و مهم ترین مباحث الگوریتم صحبت کنم؛ توابع بازگشتی. توابع بازگشتی در حل مسائل پیچیده الگوریتمی به ما کمک زیادی میکنند. مسائلی مثل جستجو و مرتب سازی و... در این مقاله با مفهوم تابع بازگشتی و کاربرد آن آشنا میشویم و مثال هایی از آن را بررسی میکنیم.تابع بازگشتی و الگوریتم بازگشتی چیست؟تابع بازگشتی به هر تابعی گفته میشود که خودش را صدا بزند. با یک مثال میتوانیم این تعریف را بهتر درک کنیم. فرض کنیم که میخواهیم یک تابع برای محاسبه فاکتوریل بنویسیم که عدد n را به عنوان ورودی دریافت میکند و فاکتوریل آن را حساب میکند.(تعریف فاکتوریل : حاصل ضرب اعداد یک تا n)یکی از ساده ترین روش های پیاده سازی این تابع استفاده از تابع بازگشتی است، به این صورت که برای محاسبه فاکتوریل n کافیست عدد n را در فاکتوریل n-1 ضرب کنیم. به همین راحتی بدون هیچ الگوریتم نویسی پیچیده میتوانیم این تابع را پیاده سازی کنیم.الگوریتم بازگشتی به الگوریتم هایی میگوییم که در پیاده سازی آنها از توابع بازگشتی استفاده میشود. در واقع در الگوریتم بازگشتی ما مسئله را به مسائل کوچک تر تقسیم میکنیم و برای آنها راه حل ارائه میدهیم.در چه زمان هایی از الگوریتم بازگشتی استفاده کنیم؟چرا باید از الگوریتم بازگشتی استفاده کنیم؟ آیا الگوریتم بازگشتی باعث بهبود عملکرد نرم افزار میشود؟ جواب این است که خیر الگوریتم بازگشتی باعث بهبود عملکرد نمیشود بلکه حتی در اکثر موارد باعث میشود حافظه کامپیوتر بیش از حد درگیر شود. پس اصلا چرا باید از آن استفاده کنیم؟ توابع بازگشتی در زمان اجرا هیچ مزیت خاصی ندارد اما در زمان طراحی الگوریتم به ما کمک زیادی میکند. در واقع تنها دلیلی که ما از توابع بازگشتی استفاده میکنیم این است که حل بعضی مسائل از طریق الگوریتم بازگشتی راحت تر است.اینکه از الگوریتم بازگشتی استفاده کنیم یا نه، بستگی به اولویت های ما دارد. آیا اینکه الگوریتم ما ساده تر باشد و بتوانیم به راحتی آن را بنویسیم مهم تر است یا اینکه بازدهی بهتر نرم افزار مهم تر است هرچند به قیمت پیچیده شدن الگوریتم باشد؟چطور یک الگوریتم بازگشتی بنویسیم؟به دلیل اینکه توابع بازگشتی خودشان را صدا میزنند، احتمال اینکه با پیاده سازی اشتباه، درگیر حلقه بی پایان شویم زیاد است. باید دقت کنیم که حتما یک حالت پایه یا همان شرط خروج برای تابع باز گشتی خودمان در نظر بگیریم، در غیر این صورت تابع بازگشتی دائما خودش را صدا میزند تا جایی که حافظه کامپیوتر پر شود و برنامه متوقف شود.حالت پایه و حالت بازگشتیالگوریتم بازگشتی، کمک میکند تا بتوانیم مسائل پیچیده رو خرد کنیم و به مسائل ساده تر تبدیل کنیم، اما این خرد کردن نباید تا ابد ادامه پیدا کند، باید یک حالت پایه برای الگوریتم در نظر بگیریم که دیگر نیاز به خرد کردن آن وجود ندارد. برای مثال به الگوریتم بازگشتی فاکتوریل توجه کنید.Factorial(n) =&gt; n * Factorial(n-1)حالت پایه این الگوریتم میتواند عدد صفر باشد، یعنی هرگاه فاکتوریل صفر از ما خواسته شد، ما دیگر مرحله بازگشتی را تکرار نمیکنیم، بلکه از پیش میدانیم که Factorial(0) مساوی یک خواهد بود. کد این الگوریتم در زبان C# به صورت زیر خواهد بودبرای اینکه درک بهتری از ساده کردن الگوریتم ها با روش تابع بازگشتی داشته باشیم، بهتر است برویم سراغ الگوریتمی که کمی پیچیده تر باشد. در یکی از مقالات قبلی درباره الگوریتم های جستجو صحبت کردیم و فلوچارت آن را کشیدیم. حالا میخواهیم جستجوی دودویی را با استفاده از تابع بازگشتی پیاده سازی کنیم. کدنویسی با زبان C# انجام شدهکامپیوتر چطور تابع بازگشتی را اجرا میکند؟زمانی که تابع بازگشتی استفاده میکنیم، کامپیوتر باید دیتای مربوط به هر مرحله را در حافظه خود ذخیره داشته باشد. وقتی توابع را درون هم صدا میزنیم، کامپیوتر باید بداند که بعد از پایان هر تابع، به کدام تابع بازگردد و دیتای مربوط به آن تابع را برگرداند. این مسائل به نظر پیچیده و کمی گیج کننده است. کامپیوتر چطور این مسائل را مدیریت میکند؟برای پاسخ این سوال ابتدا باید با یک ساختار داده دیگر آشنا شویم؛ پشته یا همان Stackپشته یا Stack چیست؟پشته یک ساختار داده است برای نگه داری از مجموعه ای از داده ها. ساختار پشته به این صورت است که داده ها یکی یکی وارد آن میشوند و پشت یکدیگر قرار میگیرند، هر زمان که بخواهیم داده های stack را بخوانیم باید از آخرین داده شروع کنیم یکی بخوانیم، یعنی هر داده ای که زود تر در پشته، وارد شده باشد دیرتر خارج خواهد شد. مانند اینکه بخواهیم تعدادی کتاب را روی یکدیگر بچینیم. اولین کتابی قرار دهیم زیر همه کتاب های بعدی قرار خواهد گرفت در نتیجه برای بیرون کشیدن آن باید از بالا یکی یکی، کتاب ها را برداریم.کامپیوتر چطور از Call Stack استفاده میکند؟کامپیوتر برای مدیریت ترتیب تابع ها از یک stack درون خودش استفاده میکند. به این شکل که هر گاه وارد تابع جدیدی میشویم اطلاعات و متغیر های مربوط به آن تابع را در پشته ذخیره میکند، اطلاعات تابع جدید در پشته روی دیتای قبلی قرار میگیرد و هرگاه عملیات آن تابع تمام شود مجددا به تابع قبلی برمیگردم که در Call Stack قبل از تابع تمام شده قرار دارد. اگر این مفهوم کمی پیچیده است، نگران نباشید فعلا لازم نیست بیشتر از این، آشنا شویم اما اگر علاقه مند هستید میتوانید درباره نحوه عملکرد آن بیشتر مطالعه کنید.نتیجه گیریالگوریتم های بازگشتی هرچند در بهبود سرعت و عملکرد نرم افزار کمکی به ما نمیکنند، اما کمک میکنند تا مسائل پیچیده را خرد کنیم و الگوریتم ساده تری برای آن بنویسیم. در واقع الگوریتم بازگشتی قرار است کار را برای برنامه نویس ساده تر کند نه کامپیوتر. نکته مهم دیگر این است که هنگام استفاده از توابع بازگشتی حتما باید دقت کنیم که شرط خروج درستی برای آن در نظر گرفته باشیم، وگرنه تابع ما، همینطور خودش را صدا میزند تا زمانی که حافظه کامپیوتر پر شود و نرم افزار متوقف شود.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Sun, 25 Feb 2024 10:37:39 +0330</pubDate>
            </item>
                    <item>
                <title>تفاوت آرایه و لیست پیوندی چیست؟</title>
                <link>https://virgool.io/@m_66394585/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-%D8%A2%D8%B1%D8%A7%DB%8C%D9%87-%D9%88-%D9%84%DB%8C%D8%B3%D8%AA-%D9%BE%DB%8C%D9%88%D9%86%D8%AF%DB%8C-%DA%86%DB%8C%D8%B3%D8%AA-usbyfyxkpjyv</link>
                <description>همان اندازه که انتخاب الگوریتم در سرعت نرم افزار اهمیت دارد، انتخاب ساختار داده مناسب هم اهمیت دارد، انتخاب ساختار داده اشتباه میتواند نرم افزار ما را به شدت کند و ناکارآمد کند. در این مقاله با دو ساختار داده پر کاربرد آشنا میشویم ؛ آرایه و لیست پیوندی. مقایسه این دو نمونه به ما کمک میکند تا در نرم افزارمان از گزینه مناسب نیازمان استفاده کنیم. در این مطلب از علامت Big O برای نشان دادن سرعت الگوریتم ها استفاده میکنیم، در صورتی که با این مفهوم آشنایی ندارید پیشنهاد میکنم این مقاله را اول بخوانید.حافظه کامپیوتر چطور کار میکند؟یک کمد بایگانی را تصور کنید، هر قفسه از آن فقط میتواند یک شیء را در خود جا دهد، بنابراین در صورتی که شما بخواهید دو چیز مختلف در آن ذخیره کنید نیاز به دو  قفسه خواهید داشت. این دقیقا طرز کار حافظه کامپیوتر شماست، حافظه کامپیوتر مانند یک کمد بایگانی بسیار بزرگ است، هر زمان که ما بخواهیم داده ای در حافظه نگه داریم، داده ما در یکی از قفسه ها قرار میگیرد و آدرس آن به ما داده میشود.اما اگر بخواهیم مجموعه ای از داده ها را ذخیره کنیم چطور؟ برای این کار دو ساختار داده ساده وجود دارد؛ آرایه و لیست پیوندی.آرایه چیست؟اگر ما بخواهیم داده های خودمان را در یک آرایه قرار بدهیم به این معناست که همه داده های ما در حافظه کامپیوتر پشت سر هم قرار گرفته اند، به مثال کمد بایگانی توجه کنید؛ اگر ما بخواهیم که 10 شیء را به صورت آرایه نگهداری کنیم باید ده قفسه پشت سر هم برای این کار در نظر بگیریم، گاهی اوقات بهتر است که تعداد بیشتری از نیازمان در نظر بگیریم تا در صورت لزوم بتوانیم شیء یازدهم را به آن اضافه کنیم، برای مثال میتوانیم 15 قفسه را رزرو کنیم اما باز هم اگر تعداد اشیائی که میخواهیم نگهداری کنیم بیشتر شود، احتمالا باید کل آرایه را جابجا کنیم و در کمد بایگانی دنبال جایی بگردیم که حداقل شانزده جای خالی پشت سر هم داشته باشد. این کار به نظر پر زحمت می آید، درست است؟ در این موارد میتوانیم به جای آرایه از لیست پیوندی استفاده کنیم.لیست پیوندی چیست؟در لیست پیوندی شما میتواند هر آیتم را در هر جایی از حافظه قرار دهید، اما باید جایگاه آیتم بعدی را هم در کنار آن آیتم قرار بدهید، در واقع لیست پیوندی مجموعه ای از داده هاست که به صورت پراکنده در حافظه ذخیره شده اند اما هر کدام به وسیله داشتن آدرس بعدی در حافظه به آن متصل شده است. برای پیدا کردن یک آیتم در لیست پیوندی باید به سراغ آیتم اول برویم، در آنجا آدرس آیتم دوم وجود دارد، بعد از آیتم دوم به سراغ آیتم سوم و بعد چهارم میرویم و همین روند را ادامه میدهیم تا آیتم مورد نظر خودمان را پیدا کنیم. اضافه کردن یک آیتم به لیست پیوندی بسیار ساده است. کافیست آیتم جدید را در هر جایی از حافظه ذخیره کنیم و آدرس آن را به آیتم قبلی بدهیم.مثالی برای درک بهترفرض کنید میخواهید با سه نفر از دوستان خود به سینما بروید، بعد از کمی جستجو سه صندلی پشت سرهم پیدا میکنید و مینشینید، کمی بعد یکی دیگر از دوستان تان با شما تماس میگیرد و میگوید که میخواهد به شما ملحق شود اما صندلی بعدی خالی نیست، در نتیجه بلند میشوید و به دنبال جایی میگردید که چهار صندلی خالی وجود داشته باشد. این طرز کار یک آرایه است به دلیل اینکه در آرایه لازم است همه آیتم ها پشت سر هم باشند، در صورتی که تعداد آیتم ها از چیزی که شما در نظر گرفتید بیشتر شود باید همه آیتم ها را جابجا کنید و طبیعتا این کار زمان زیادی خواهد برد.اما درباره لیست پیوندی این مسئله وجود ندارد، چون هر آیتمی میتواند در هر جایی از حافظه ذخیره شود، مانند اینکه با ده نفر از دوستان تان به سینما بروید و بجای اینکه دنبال جایی بگردید که ده صندلی خالی داشته باشد، پراکنده شوید و هر کدام یک صندلی خالی برای نشستن پیدا کنید.مقایسه عملکرد آرایه و لیست پیوندیبعد از اینکه با این دو ساختار داده آشنا شدیم، حالا باید به این سوال جواب بدهیم که از کدام یک باید استفاده کنیم؟ در حقیقت یک جواب قطعی برای این سوال وجود ندارد. با توجه به نیاز نرم افزار در هر موردی باید از ساختار داده مناسب استفاده کنیم. در ادامه لیست پیوندی و آرایه را از جهت سرعت و بازدهی در موقعیت های مختلف مقایسه میکنیم.تفاوت سرعت در پیدا کردن اطلاعاتفرض کنید ما میخواهیم آیتم 100 ام از یک آرایه را بخوانیم، کار بسیار راحتی خواهد بود کافی است از آدرس آیتم اول، نود و نه خانه به جلو برویم. پس عملا ما با یک عملیات آیتم صدم را پیدا میکنیم، بنابراین پیچیدگی زمانی آن، O(1) خواهد بود.اما درباره لیست پیوندی، قضیه متفاوت خواهد بود، برای پیدا کردن آیتم صدم در لیست پیوندی ابتدا باید آیتم یک را پیدا کنیم سپس آدرس آیتم دوم را در آنجا پیدا کنیم، بعد آیتم سوم و چهارم و… همین روند را ادامه بدهیم تا بالاخره به آیتم صدم برسیم. به عبارتی باید خانه ها را یکی یکی به جلو بیاییم پس پیچیدگی زمانی پیدا کردن آیتم در لیست پیوندی به صورت O(n) خواهد بود.تفاوت سرعت در اضافه یا حذف کردن دیتابه نظر میرسد اضافه کردن دیتا به آرایه کار راحتی است، کافیست بعد از آخرین آیتم، یک آیتم جدید قرار دهیم. اما مسئله، زمانی پیچیده میشود که بخواهیم به اول یا اواسط یک آرایه آیتم جدید اضافه کنیم، در این صورت لازم داریم که تمام آیتم های بعدی را به یک خانه جلوتر منتقل کنیم. برای مثال اگر ما یک آرایه داشته باشیم که در حال حاضر ده عضو داشته باشد و بخواهیم به اول آن یک آیتم جدید اضافه کنیم باید آیتم یک را ببریم بجای آیتم دو و آیتم دو بجای آیتم سه ببریم و همین روند را ادامه دهیم تا همه آیتم ها یک خانه جابجا شوند و بتوانیم آیتم جدید را در خانه اول بگذاریم. اضافه کردن به میانه آرایه هم فرایند مشابهی دارد.همین روند برای حذف کردن دیتا هم وجود دارد. باید تمام آیتم های بعد از آیتم حذف شده، یک خانه به عقب برگردند. برای حذف و اضافه کردن در آرایه، ممکن است نیاز پیدا کنیم تا همه آیتم ها را جابجا کنیم، پس میتوانیم بگوییم که پیچیدگی زمانی این فرایند به صورت O(n) خواهد بود.اما درباره لیست پیوندی چطور؟ اضافه کردن در لیست پیوندی بسیار ساده است، آیتم جدید را در هر جایی از حافظه که بخواهیم قرار میدهیم و آدرس آن را در آیتم قبلی قرار میدهیم. فرض کنیم که یه لیست پیوندی با 10 آیتم داریم و میخواهیم آیتم جدیدی بین آیتم 3 و 4 اضافه کنیم. کافیست آیتم جدید را در جایی از حافظه قرار دهیم و آدرس آن را به آیتم 3 بدهیم و آدرس آیتم 4 را به آیتم جدید بدهیم. بدون اینکه نیاز به جابجایی دیتا های قبلی وجود داشته باشد.حذف کردن از لیست پیوندی نیز کار راحتی خواهد بود، کافییست آیتم مورد نظر را از حافظه حذف کنیم و آدرس آیتم بعدی را به آیتم قبلی بدهیم. اضافه و حذف کردن در لیست پیوندی با یک عملیات انجام خواهد شد پس پیچیدگی زمانی آن به صورت O(1) خواهد بود.جمع بندیآرایه و لیست پیوندی، دو تا از مهم ترین ساختار های داده هستند که وقتی با مجموعه ای از داده ها کار داشته باشیم، باید سراغ آنها برویم.اینکه سراغ کدام یک برویم بستگی به نیاز ما دارد. اگر قرار است که مجموعه ای داشته باشیم که مدام به آن اضافه یا از آن حذف کنیم، بهتر است از لیست پیوندی استفاده کنیم. برای مثال اگر بخواهیم یک نرم افزار todo list بنویسیم که کار هایمان را در آن قرار دهیم بهتر است از لیست پیوندی استفاده کنیم چون مدام نیاز داریم میان کارهای قبلی، کار جدیدی اضافه کنیم و کار هایی که انجام میدهیم را از لیست حذف کنیم.اما اگر مجموعه داده های ما تغییرات زیادی ندارد و ما نیاز داریم که مدام از میانه آن آیتم های مان را بخوانیم بهتر است از آرایه کمک بگیریم، برای مثال اگر بخواهیم یک نرم افزار دیکشنری بنویسیم بهتر است از آرایه برای نگهداری لغات استفاده کنیم به دلیل اینکه لغات دیکشنری معمولا کم و زیاد نمیشود اما در عوض همیشه نیاز داریم که کلمه مورد نظرمان را بین کلمات پیدا کنیم.در آخر این نکته را یادآوری کنم که مثال ها، جنبه آموزشی دارند و در ادامه که بیشتر با ساختار های داده آشنا میشویم، میفهمیم که راه حل های بهتری هم برای این مسائل وجود دارد.اگر این مطلب برایتان مفید بود، پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده را دنبال کنید.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Tue, 20 Feb 2024 19:40:02 +0330</pubDate>
            </item>
                    <item>
                <title>چگونه سرعت الگوریتم ها را محاسبه کنیم؟ Big O</title>
                <link>https://virgool.io/@m_66394585/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%B3%D8%B1%D8%B9%D8%AA-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D9%87%D8%A7-%D8%B1%D8%A7-%D9%85%D8%AD%D8%A7%D8%B3%D8%A8%D9%87-%DA%A9%D9%86%DB%8C%D9%85-big-o-cwc8tgkgdfa0</link>
                <description>در مقاله قبلی در اینباره صحبت کردیم که بهبود کارایی الگوریتم ها در برنامه نویسی، امری ضروری و مهم است و رعایت نکردن آن میتواند نرم افزار ما را کُند و یا حتی غیر قابل استفاده کند. در این مقاله میخواهیم کمی دقیق تر شویم و ببینیم که چطور میتوان سرعت الگوریتم ها را حساب کرد؟ چه معیاری نشان میدهد یک الگوریتم سریع تر از دیگری است؟ با علامت Big O آشنا میشویم و یاد میگیریم که چطور از آن برای نشان دادن سرعت الگوریتم ها استفاده کنیم و سعی میکنیم با بررسی مثال هایی، این مطلب را کاربردی تر و ساده تر کنیم.معیار سریع بودن الگوریتم ها چیست؟برای محاسبه سرعت الگوریتم ها، ما فرض میگیریم که کامپیوتر، هر عملیات را در یک واحد زمانی انجام میدهد. (تفاوت سرعت انجام عملیات ها به قدری کم است که از آن صرف نظر میکنیم). پس با این فرض میتوانیم بگوییم الگوریتمی سریع تر است که تعداد عملیات کمتری انجام دهد، مهم نیست که الگوریتم شما در چند خط نوشته میشود مهم این است که تعداد عملیات هایی که کامپیوتر برای رسیدن به جواب انجام میدهید، چقدر است؟علامت O بزرگ چیست؟ما از علامت O بزرگ برای نشان دادن مرتبه زمانی الگوریتم ها استفاده میکنیم. این علامت به ما نشان میدهد که الگوریتم ما به ازای هر تعداد ورودی چند عملیات انجام خواهد داد. مرتبه های زمانی بسیار زیادی وجود دارد اما در اینجا ما فقط سه مورد از آنها را به عنوان نمونه بررسی میکنیم:1.     مرتبه زمانی ثابت O(1)مرتبه زمانی ثابت یعنی ورودی ما هرچقدر هم بزرگ یا کوچک باشد تفاوتی نمیکند در نهایت، الگوریتم ما فقط یک عملیات انجام خواهد داد، برای مثال الگوریتمِ برگرداندن آخرین عضو یک آرایه؛ تفاوتی نمیکند که این آرایه چند عضو داشته باشد در نهایت الگوریتم با انجام یک عملیات خروجی را به ما خواهد داد. نمودار پیچیدگی زمانی این الگوریتم به صورت زیر خواهد بود:2.     مرتبه زمانی خطی O(n)مرتبه زمانی خطی یعنی تعداد عملیات ها متناسب با تعداد ورودی ها تغییر میکند، یعنی اگر ما تعداد ورودی ها را دو برابر کنیم تعداد عملیات هم دو برابر خواهد شد، مثال برای مرتبه زمانی خطی، «جستجوی خطی در لیست» است که در مقاله قبلی درباره آن صحبت کردیم و فلوچارت آن را کشیدیم، نمودار پیچیدگی زمانی جستجوی خطی به صورت زیر خواهد بود:3.     مرتبه زمانی لگاریتمی O(log n)مرتبه زمانی لگاریتمی به این معناست که تعداد عملیات های لازم برای الگوریتم متناسب است با لگاریتمِ تعداد ورودی ها. شاید تعریفی که گفته شد کمی ناواضح باشد. در واقع مرتبه زمانی لگاریتمی به این معناست که اگر ما تعداد ورودی ها را دو برابر کنیم، تعداد عملیات ها تنها یکی بیشتر میشود. در مقاله قبلی با الگوریتم جستجوی دودویی آشنا شدیم، این الگوریتم مثال خوبی برای پیچیدگی زمانی لگاریتمی است. نمودار پیچیدگی زمانی لگاریتمی به شکل زیر خواهد بود:چطور پیچیدگی زمانی را محاسبه کنیم؟تا اینجا فهمیدیم که علامت O بزرگ برای نشان دادن پیچیدگی زمانی الگوریتم ها استفاده میشود، اما در محاسبه پیچیدگی زمانی باید به چند نکته بسیار مهم توجه داشت:1.     عدم اهمیت ضریب هافرض کنیم ما الگوریتمی داریم که به ازای n ورودی، تعداد عملیات آن برابر با 10n خواهد بود، اگر بخواهیم پیچیدگی زمانی این الگوریتم را نشان دهید، چطور این کار را میکنید؟ شاید به ذهن تان برسد که پیچیدگی زمانی به صورت O(10n) خواهد بود اما این جواب اشتباه است به دلیل این که در محاسبه پیچیدگی زمانی ضریب ها اهمیتی ندارند و آنها را نادیده میگیریم پس پیچیدگی زمانی این الگوریتم به صورت پیچیدگی زمانی خطی یا همان O(n) خواهد بود.2.     سرعت رشد زمان الگوریتمدر واقع ما از پیچیدگی زمانی برای نشان دادن سرعت الگوریتم ها استفاده نمیکنیم، پیچیدگی زمانی به ما نمیگوید که یک الگوریتم، در چه مدت زمانی کار را انجام میدهد، بلکه سرعت رشد زمان را در نسبت با بزرگ شدن ورودی میگوید. و دقیقا این همان چیزی است که برای ما اهمیت دارد، ما میخواهیم بدانیم که الگوریتم ما با بزرگ شدن ورودی ها چقدر کند میشود و آیا میتواند کارایی خودش را حفظ کند یا نه؟3.     در نظر گرفتن حالت بدبینانهبرای محاسبه پیچیدگی زمانی ما باید حالت بدبینانه آن را در نظر بگیریم، برای مثال الگوریتم جستجوی خطی را در نظر بگیرید، ممکن است به طور اتفاقی اولین عضوی که ما بررسی میکنیم همان عضو مد نظر باشد ولی این معنا نیست که ما توانیم بگوییم پیچیدگی زمانی آن برابر با O(1) است، بلکه ما باید حالت بدبینانه را در نظر بگیریم و فرض کنیم که آخرین عضوی که بررسی میکنیم عضو مورد نظر بوده پس پیچیدگی زمانی برابر با O(n) خواهد شدنتیجه گیریدر این مقاله با مفهوم پیچیدگی زمانی آشنا شدیم و یاد گرفتیم چطور تشخیص بدهیم که یک الگوریتم، به ازای ورودی های بزرگ تر چقدر کُند میشود. با علامت O بزرگ آشنا شدیم و یاد گرفتیم که چطور به وسیله آن پیچیدگی زمانی را نشان دهیم. با مرتبه های زمانی آشنا شدیم و نمودارهایشان را دیدیم. در ادامه این دانش به ما کمک خواهد کرد که الگوریتم های کارآمد و بهینه تری بنویسیم. در مقالات بعدی از این دانش استفاده بیشتری خواهیم کرد.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، اگر علاقه مند هستید پیشنهاد میکنم سری مقالات الگوریتم و ساختمان داده رو مطالعه کنید. ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Thu, 15 Feb 2024 21:31:56 +0330</pubDate>
            </item>
                    <item>
                <title>تاثیر الگوریتم در سرعت نرم افزار – مقایسه سرعت الگوریتم های جستجو</title>
                <link>https://virgool.io/@m_66394585/%D8%AA%D8%A7%D8%AB%DB%8C%D8%B1-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D8%AF%D8%B1-%D8%B3%D8%B1%D8%B9%D8%AA-%D9%86%D8%B1%D9%85-%D8%A7%D9%81%D8%B2%D8%A7%D8%B1-%D9%85%D9%82%D8%A7%DB%8C%D8%B3%D9%87-%D8%B3%D8%B1%D8%B9%D8%AA-%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%D9%87%D8%A7%DB%8C-%D8%AC%D8%B3%D8%AA%D8%AC%D9%88-gaiv0lfaxy24</link>
                <description>الگوریتم ها نقش بسیار مهمی در توسعه نرم افزار دارند، انتخاب الگوریتم نامناسب میتواند نرم افزار ما را به شدت کند و غیر کاربردی کند. در این مقاله میخواهیم دقیق تر این موضوع را بررسی کنیم و ببینیم که اشتباه در انتخاب الگوریتم ممکن است چه تاثیری بر نرم افزار ما داشته باشد. آیا واقعا انتخاب درست الگوریتم آنقدر ها که میگویند مهم است؟ برای فهمیدن جواب این سوال بهتر است با یک مثال کاربردی پیش برویم. فرض کنید ما میخواهیم یک الگوریتم جستجو بنویسیم تا بتوانیم از آن در یک دیکشنری دیجیتال (یا هر چیز دیگر) استفاده کنیم. چه روش هایی برای نوشتن این الگوریتم داریم؟چه الگوریتم هایی برای جستجو وجود دارد؟احتمالا اولین و ساده ترین الگوریتمی که به ذهن مان میرسید این است که ی کلمه جستجو شده را یک به یک با کلماتی که در دیکشنری داریم مقایسه کنیم. به این روش «جستجوی خطی» میگویند، این روش ساده، برای تعداد کلمات پایین به خوبی کار میکند اما در تعداد کلمات بالا این فرایند بسیار طولانی خواهد شد، آیا روش دیگری هم برای جستجو وجود دارد؟ به طور کلی دو الگوریتم معروف برای حل این مسئله وجود دارد :جستجوی خطیجستجوی دودوییالگوریتم جستجوی خطیهمانطور که گفتیم الگوریتم جستجوی خطی به این روش است که ما کلمه مورد نظر خودمان را با تک تک کلمات موجود در لیست مقایسه میکنیم تا به نتیجه برسیم، الگوریتم به شکل زیر خواهد بود:طبیعتا بررسی کردن کل کلمات یک دیکشنری کار زمان بر و بیهوده ای است و به راحتی میتوان گفت که این الگوریتم بهینه و سریع نیست، پس بهتر است با الگوریتم جستجوی دیگری آشنا شویم.الگوریتم جستجوی دودویی (Binary Search)جستجوی دودویی بسیار سریع تر از روش خطی عمل میکند، در این روش ما ابتدا کلمه ای را که در وسط دیکشنری قرار دارد پیدا میکنیم و آن کلمه را با کلمه مورد نظر خودمان مقایسه میکنیم اگر کلمه مورد نظر را پیدا کردیم که نتیجه روشن است، اما اگر پیدا نکردیم باید ببینیم که کلمه مورد نظر در ترتیب الفبا بعد از آن کلمه است یا قبل از آن. اگر بعد از آن باشد ما نیمه اول دیکشنری را کنار میگذاریم و مجددا نیمه دوم دیکشنری را به دو بخش تقسیم میکنیم و همان روند را تکرار میکنیم، اگر هم کلمه مورد نظر قبل از کلمه ای که پیدا کردیم باشد نیمه دوم دیکشنری را کنار میگذاریم و نیمه اول را به دو بخش تقسیم میکنیم و...فلوچارت جستجوی دودویی به روش زیر خواهد بود:نکته مهمی که درباره جستجوی دودویی وجود دارد این است که ای ن روش تنها برای لیست هایی ممکن است که مرتب شده باشند. اگر ما لیستی غیر مرتب داشته باشیم به ناچار باید از روش خطی استفاده کنیم که به شدت زمان بر است.چطور بفهمیم که یک الگوریتم سریع تر از دیگری است؟تا اینجا فهمیدیم که انتخاب الگوریتم مناسب تاثیر خیلی زیادی بر سرعت نرم افزار دارد، اما از کجا بفهمیم که در هر موردی چه الگوریتمی سریع تر است؟ قاعده کلی این است که «الگوریتمی که تعداد عملیات کمتری انجام دهد الگوریتم سریع تری است» برای مثال ما برای پیدا کردن یک کلمه در یک دیکشنری چند هزار کلمه ای با روش خطی باید هزاران عملیات انجام دهیم اما با روش دودویی کمتر از 50 عملیات خواهیم داشت. اما باید توجه داشت که این اختلاف سرعت در اعداد بزرگ خودش را نشان میدهد و در اعداد کوچک تر، تمام الگوریتم ها سرعت های نزدیک بهم دارند. معمولا برای نشان دادن سرعت الگوریتم از علامت O بزرگ استفاده میشود که روش محاسبه و استفاده از آن را حتما در مقالات بعدی توضیح خواهیم داد.نتیجه گیریدر این مقاله فهمیدیم که انتخاب درست الگوریتم چقدر در سرعت نرم افزار تاثیر گذار است، با روش جستجوی خطی و دودویی آشنا شدیم و همچنین فهمیدیم که چطور سرعت دو الگوریتم را با یکدیگر مقایسه کنیم (البته در آینده بیشتر در این مورد صحبت خواهیم کرد). امیدوارم که این مقاله برایتان مفید بوده باشد، اگر علاقه مند هستید پیشنهاد میکنم حتما سری مقالات الگوریتم و ساختمان داده را دنبال کنید.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Sat, 10 Feb 2024 13:11:16 +0330</pubDate>
            </item>
                    <item>
                <title>الگوریتم چیست و چرا برای برنامه نویسی مهم است؟</title>
                <link>https://virgool.io/codenevis/%D8%A7%D9%84%DA%AF%D9%88%D8%B1%DB%8C%D8%AA%D9%85-%DA%86%DB%8C%D8%B3%D8%AA-%D9%88-%DA%86%D8%B1%D8%A7-%D8%A8%D8%B1%D8%A7%DB%8C-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87-%D9%86%D9%88%DB%8C%D8%B3%DB%8C-%D9%85%D9%87%D9%85-%D8%A7%D8%B3%D8%AA-jzkwdckxqxdk</link>
                <description>در دنیای برنامه نویسی الگوریتم ها از نقش بسیار مهمی برخوردارند، الگوریتم ها در دنیای نرم افزار مانند قوانین فیزیک در دنیای واقعی هستند؛ هر کدی که ما مینویسیم در واقع یک الگوریتم است بنابراین خیلی مهم است که با روش های مختلف الگوریتم نویسی آشنا شویم تا بتوانیم از آنها در کد هایمان به روش صحیح استفاده کنیم. در این مقاله قصد داریم تا با مفهوم الگوریتم آشنا شویم و درباره اهمیت آنها در برنامه نویسی صحبت کنیم.الگوریتم چیست؟طبق تعریف : « الگوریتم مجموعه ای ترتیب دار از دستورات است که برای انجام کاری مشخص استفاده میشوند».برنامه نویس ها معمولا الگوریتم را به دستور پخت غذا تشبیه میکنند. دستورالعمل پخت غذا گام به گام، مراحل درست کردن غذا را از مواد اولیه توضیح میدهد پس در واقع نوعی الگوریتم محسوب میشود. به طور کلی الگوریتم ها از سه قسمت اصلی تشکیل میشوند:1.     ورودیالگوریتم ها معمولا مقادیری به عنوان ورودی دارند که دستورات روی آنها انجام میشود، برگردیم به همان مثال دستور پخت غذا؛ هر دستور غذایی نیاز به یک سری مواد اولیه دارد که میتواند چیز های مختلفی باشد مثل تخم مرغ، گوشت، ادویه، روغن و....   در مورد الگوریتم ها هم همینطور است. برای مثال الگوریتم &quot;جستجوی دودویی&quot; نیاز به یک لیست مرتب شده و یک مقدار مشخص برای جستجو دارد در مقالات بعدی در اینباره بیشتر صحبت میکنیم.2.     سلسله دستوراتمهم ترین بخش هر الگوریتم سلسله دستورات است، نکته مهم که در تعریف هم گفته شد این است که این دستورات ترتیب دارند بنابر این ما به یک لیست وسایل سفر نمیتوانیم بگوییم الگوریتم. در یک دستور العمل غذا همیشه ترتیب وجود دارد و اگر کار ها بدون در نظر گرفتن آن ترتیب انجام شود در نهایت به خروجی دلخواهمان نمیرسیم.3.     خروجیخروجی در واقع همان هدفی است که ما الگوریتم را برای آن نوشته ایم، مهم ترین معیار بررسی یک الگوریتم این است که خروجی درستی به ما بدهد، اینکه الگوریتم سریع و بهینه باشد در اولویت دوم است (البته نه همیشه، در مقالات بعدی بیشتر توضیح میدهم)، طبیعتا انتظار ما این است که اگر ورودی درست باشد و سلسله دستورات هم به ترتیب و با دقت انجام شده باشد خروجی هم درست باشد. اگر مواد اولیه را به درستی تهیه کرده باشیم و تمام مراحل را طبق دستور العمل پیش رفته باشیم باید به غذای خوشمزه و مطلوبی برسیم وگرنه بدون شک دستور پخت غذا مشکل داشته است.الگوریتم نویسی در دنیای برنامه نویسی چه کاربردی دارد؟همان طور که گفتیم هر کدی که ما مینویسیم نوعی الگوریتم است اما به سه دلیل مهم ما باید حتما مفاهیم الگوریتم نویسی و ساختمان داده را یاد بگیریم1.     حل مسائل پیچیدهشاید بتوانیم مسائل ساده برنامه نویسی را بدون دانش الگوریتم نویسی حل کنیم اما برای مسائل پیچیده تر بدون دانستن این مفاهیم به مشکل میخوریم برای مثال شاید شما بتوانید برج هانوی را با سه یا چهار دیسک به راحتی حل کنید و الگوریتم آن را بنویسید اما آیا میتوانید همین کار را برای هزار دیسک انجام دهید؟ اگر بیشتر باشد چطور؟ حل مسائل پیچیده برنامه نویسی بدون دانش الگوریتم اگر غیرممکن نباشد بسیار دشوار است.2.     افزایش سرعت مسئلهدر برخی مسائل ممکن است ما بتوانیم بدون دانش الگوریتم هم مسائل را حل کنیم اما سرعت الگوریتمی که به دست می آید بسیار پایین تر از یک الگوریتم بهینه است، البته اختلاف سرعت الگوریتم ها در اعداد بزرگ خودش را نشان میدهد (در مقالات بعدی بیشتر در اینباره صحبت میکنیم) برای اینکه بیشتر متوجه اهمیت این مورد بشویم بهتر است یک مثال بزنیم: فرض کنید ما یک مجموعه ای از یک میلیارد عدد داریم و میخواهیم یک عدد را در این مجموعه پیدا کنیم، برای این کار دو الگوریتم وجود دارد : جستجوی خطی  و جستجوی دودویی (در مقالات بعدی درباره هر یک از این ها بیشتر صحبت میکنیم)اگر فرض کنیم که بررسی کردن هر عدد یک ثانیه طول میکشد، پیدا کردن این عدد با روش خطی بیش از 37 سال طول میکشد در صورت که با جستجوی دودویی فقط 30 ثانیه طول خواهد کشید و این اختلاف در اعداد بزرگتر به مراتب بیشتر خواهد شد. پس بسیار مهم است که الگوریتم هایی با بالاترین سرعت ممکن بنویسیم.3.     استفاده بهینه از منابع سیستمنرم افزار هایی که ما مینویسیم قرار است توسط سخت افزار ها اجرا شوند و همه ما به خوبی میدانیم که با وجود پیشرفت تکنولوژی هنوز سخت افزار ها محدودیت های زیادی دارند پس ما باید الگوریتم های مان را طوری بهینه کنیم که از منابع سیستم به درستی استفاده کنیم تا بیشترین بازدهی را بگیریم، در مباحث ساختمان داده بیشتر در اینباره صحبت خواهیم کرداز کجا الگوریتم یاد بگیریم؟در مقاله قبلی یک کتاب بسیار عالی برای یادگیری الگوریتم معرفی کردم، اما اگر مطالعه این کتاب برایتان دشوار است میتوانید سری مقالات الگوریتم و ساختمان داده من را مطالعه کنید، در این مقالات سعی کردم که مفاهیم الگوریتم را به صورت جامع و کاربردی اما به زبان ساده توضیح دهم امیدوارم که برایتان مفید باشد.خیلی ممنون از اینکه وقت گذاشتید و این مقاله رو مطالعه کردید، ممنون میشم نظرتون رو بهم بگید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Mon, 05 Feb 2024 10:31:56 +0330</pubDate>
            </item>
                    <item>
                <title>بهترین کتاب برای یادگیری الگوریتم - معرفی کتاب Grokking Algorithms</title>
                <link>https://virgool.io/codenevis/best-book-to-learn-algorithm-q4xqpxl0ageq</link>
                <description>الگوریتم و ساختمان داده همیشه یکی از مباحث سخت علوم کامپیوتر محسوب میشده. کسانی که قصد یادگیری این موضوع را داشتند، باید بین کتاب های پیچیده و سنگین جستجو میکردند و از آنها یاد میگرفتند. اما آیا تا به حال به این فکر کرده اید که یک راهنمای تصویری چقدر به شما کمک کند تا این مفاهیم پیچیده را با سادگی و جذابیتی بی‌نظیر یاد بگیرید؟ اگر به دنبال یادگیری الگوریتم‌ها و ساختمان داده با روشی نوآورانه و متفاوت هستید، &quot;Grokking Algorithms&quot; کتابی اساسی است که نور به تاریکی‌های دنیای الگوریتم می‌اندازد.آشنایی با کتاب &quot;Grokking Algorithms&quot;کتاب &quot;Grokking Algorithms&quot; نوشته‌ی آدیتیا بارگاوا، یکی از کتاب‌هایی است که با رویکرد تصویری و زبان ساده به آموزش الگوریتم‌ها و ساختارهای داده می‌پردازد. نویسنده در این کتاب، از تصاویر و نمودارهای واضح و قابل فهم استفاده می‌کند تا مفاهیم پیچیده را برای همه قابل درک کند. این روش تدریس، محتوایی جذاب برای یادگیری الگوریتم‌ها به شما ارائه می‌دهد که حتماً خواننده‌ها را به سمت ادامه‌ی مسیر می‌کشاند.کشف جذابیت مباحث پیچیدهکتاب &quot;Grokking Algorithms&quot; با استفاده از مثال‌های متنوع و جذاب، مفاهیم پیچیده الگوریتم‌ها و ساختارهای داده را به سادگی توضیح می‌دهد. شما با خواندن این کتاب، به دنیایی از مثال‌های واقعی و کاربردی وارد می‌شوید که به شما کمک می‌کند مفاهیم تئوری را به صورت عملی درک کنید. از الگوریتم‌های مرسوم مانند جستجوی دودویی و مرتب‌سازی تا موارد پیچیده‌تر مانند الگوریتم‌های گراف، هر مبحث به شیوه‌ای که شما احساس می‌کنید داستان را دنبال می‌کنید، توضیح داده می‌شود.راهنمای یادگیری تصویرییکی از نکات برجسته در &quot;Grokking Algorithms&quot;، استفاده از تصاویر و نمودارها برای توضیح مفاهیم است. این کتاب برخلاف کتب دیگر، با ترکیب متن با تصاویر و نمودارها، تئوری‌های پیچیده را برای چشم‌ها و ذهن شما جذاب و قابل درک می‌کند. این روش به شما این امکان را می‌دهد که حتی بدون داشتن پیش‌زمینه کامل در علوم کامپیوتر، به راحتی مفاهیم را متوجه شوید و در زمان کمتر به مبحث الگوریتم مسلط شوید.نتیجه گیریکتاب &quot;Grokking Algorithms&quot; به شما فرصتی منحصر به فرد برای یادگیری مفاهیم پیچیده الگوریتم‌ها و ساختارهای داده می‌دهد. با استفاده از روش تصویری و مثال‌های جذاب، نویسنده، شما را به دنیایی از اطلاعات و تجربیات هدایت می‌کند که از آن به عنوان یک برنامه‌نویس مسلط و آگاه، بهره‌برداری خواهید کرد. اگر به دنبال راهی جدید برای یادگیری الگوریتم‌ها هستید، این کتاب برای شما یک انتخاب بسیار مناسب است.امیدوارم این نوشته برایتان مفید بوده باشد، خوشحال میشوم نظرتان را با من به اشتراک بگذارید.منبع : سری مقالات الگوریتم و ساختمان داده از سایت خودم</description>
                <category>امیرحسین محسنی</category>
                <author>امیرحسین محسنی</author>
                <pubDate>Wed, 31 Jan 2024 20:06:10 +0330</pubDate>
            </item>
            </channel>
</rss>