ساخت الگوریتم های گراف در سوئیفت — به زبان ساده

۲۴۵ بازدید
آخرین به‌روزرسانی: ۱۲ مهر ۱۴۰۲
زمان مطالعه: ۴ دقیقه
ساخت الگوریتم های گراف در سوئیفت — به زبان ساده

گراف یک ساختمان داده است که روابط (یعنی اتصال) را بین دو یا چند شیء نمایش می‌دهد. گراف‌ها به دلیل انعطاف‌پذیری‌شان یکی از پرکاربردترین ساختارهای مورد استفاده در محاسبات مدرن محسوب می‌شوند. ابزارها و سرویس‌های رایجی مانند نقشه‌های آنلاین، شبکه‌های اجتماعی و حتی اینترنت در کلیت خود بر مبنای ارتباط اشیا با همدیگر طراحی شده‌اند. در این مطلب، قابلیت‌های کلیدی گراف‌ها را بررسی می‌کنیم و شیوه ایجاد الگوریتم های گراف در سوئیفت را معرفی خواهیم کرد.

مبانی گراف

چنان که در بخش قبل اشاره کردیم، گراف یک مدل است که شیوه ارتباط اشیا با همدیگر را نمایش می‌دهد. اشیای گراف معمولاً به صورت گره‌ها و رأس‌ها مورد اشاره قرار می‌گیرند. با این که می‌توان گرافی با تنها یک گره ساخت، اما مدل‌هایی که شامل چندین رأس هستند، اپلیکیشن‌های دنیای واقعی را به شیوه بهتری نمایندگی می‌کنند.

اشیای گراف از طریق اتصال‌هایی به نام یال با هم ارتباط برقرار می‌کنند. بسته به الزامات، یک رأس می‌تواند یک یا چند شیء را از طریق یال‌هایی به هم مرتبط سازد. همچنین امکان ایجاد یک رأس بدون یال وجود دارد. در ادامه به برخی پیکربندی‌های مقدماتی گراف اشاره کرده‌ایم:

 الگوریتم های گراف در سوئیفت
یک گراف غیر جهت‌دار با دو رأس و یک یال
 الگوریتم های گراف در سوئیفت
یک گراف غیر جهت‌دار با سه رأس و سه یال
 الگوریتم های گراف در سوئیفت
یک گراف غیر جهت‌دار با چهار رأس و سه یال

جهت‌دار یا غیر جهت‌دار

چنان که در بخش قبل دیدیم، روش‌های زیادی برای پیکربندی یک گراف وجود دارد. یک گزینه اضافی برای تنظیم مدل به صورت جهت‌دار یا غیر جهت‌دار نیز وجود دارد. نمونه‌های فوق همگی گراف‌های غیر جهت‌دار را نشان می‌دادند. به بیان دیگر اتصال بین رأس‌های A و B معادل اتصال بین رأس‌های B و A است. شبکه‌های اجتماعی نمونه‌ای عالی از گراف‌های غیر جهت‌دار هستند. زمانی که درخواستی پذیرفته می‌شود، هر دو طرف (فرستنده و گیرنده) اتصال دوطرفه‌ای با هم پیدا می‌کنند.

سرویسی مانند Google Maps نمونه‌ای عالی از یک گراف جهت‌دار است. برخلاف یک گراف غیر جهت‌دار، گراف‌های جهت‌دار تنها از اتصال یک طرفه بین رأس‌ها و مقاصدشان پشتیبانی می‌کنند. بنابراین برای مثال رأس A می‌تواند به رأس B وصل شود، اما A لزوماً از طریق B قابل دسترسی نیست. برای نمایش تنوع روابط بین رأس‌ها، گراف‌های جهت‌دار با استفاده از خط‌ها و فلش‌ها ترسیم می‌شوند.

یال و وزن

صرف‌نظر از نوع گراف، سطح اتصال بین رأس‌ها نیز معمولاً نمایش می‌یابد. به طور معمول وزن با یک یال مرتبط است و یک مقدار عددی دارد که برای مقصد خاصی تعیین شده است. چنان که خواهیم دید، مدل‌سازی یک گراف با وزن‌های یال می‌تواند برای حل طیف وسیعی از مسائل مورد استفاده قرار گیرد.

 الگوریتم های گراف در سوئیفت
یک گراف جهت‌دار با سه رأس و سه یال وزن‌دار

رأس

اینک با درکی که از گراف در دست داریم، می‌توانیم شروع به ساخت یک گراف جهت‌دار ابتدایی با وزن‌های یال بکنیم. برای شروع، یک ساختمان داده را می‌بینید که می‌تواند نماینده یک رأس باشد:

1public class Vertex {
2    
3    var key: String?
4    var neighbors: Array<Edge>
5init() {
6        self.neighbors = Array<Edge>()
7    }
8        
9}

همچنان که در ساختارهای دیگر دیدیم، کلید نماینده داده‌هایی است که با یک وهله از کلاس مرتبط هستند. برای این که همه چیز سرراست باشد، کلید ما به صورت یک رشته اعلان می‌شود. در اپلیکیشن‌های عملی، نوع کلید می‌تواند با یک placeholder ژنریک مانند <T> جایگزین شود. بدین ترتیب می‌توانیم از کلید برای ذخیره‌سازی هر چیزی مانند یک عدد صحیح، حساب یا پروفایل استفاده کنیم.

فهرست همسایگی (ADJACENCY LISTS)

مشخصه همسایگی، آرایه‌ای است که اتصال‌های ممکن از یک رأس به دیگر رئوس را نشان می‌دهد. چنان که قبلاً توضیح دادیم یک رأس می‌تواند با یک یا چند رأس دیگر مرتبط باشد. آیتم‌های فهرست همسایگی گاهی اوقات به نام ADJACENCY LISTS نیز نامیده می‌شوند و می‌توانند برای حل برخی از مسائل مورد استفاده قرار گیرند. در ادامه یک ساختمان داده ابتدایی را می‌بیند که یک یال را نمایش می‌دهد:

1public class Edge {
2    
3    var neighbor: Vertex
4    var weight: Int
5    
6    init() {
7        weight = 0
8        self.neighbor = Vertex()
9    }
10    
11}

ساخت گراف

اکنون که اشیای رأس و یال ساخته شده‌اند، می‌توانیم از این ساختمان‌ها برای ساخت گراف استفاده کنیم. برای این که همه چیز سرراست بماند، فعلاً روی عملیات اساسی افزودن و پیکربندی رئوس متمرکز می‌شویم:

1public class Edge {
2    
3    var neighbor: Vertex
4    var weight: Int
5    
6    init() {
7        weight = 0
8        self.neighbor = Vertex()
9    }
10    
11}

تابع addVertex یک رشته می‌پذیرد که برای ایجاد یک رأس جدید مورد استفاده قرار می‌گیرد. کلاس SwiftGraph یک مشخصه خصوصی به نام canvas نیز دارد که برای مدیریت همه رئوس استفاده می‌شود. از canvas برای ردگیری و مدیریت رأس‌ها با یا بدون یال‌ها می‌تواند استفاده شود، گرچه الزامی نیست.

ایجاد اتصال‌ها

زمانی که رأسی اضافه شد، می‌تواند به رئوس دیگر وصل شود. فرایند تثبیت یک یال به صورت زیر است:

1public class SwiftGraph {
2       
3    //declare graph canvas
4    private var canvas: Array<Vertex>
5    public var isDirected: Bool    
6    
7    init() {
8        canvas = Array<Vertex>()
9        isDirected = true
10    }
11        
12    //create a new vertex
13    func addVertex(key: String) -> Vertex {        
14        
15        //set the key
16        let childVertex: Vertex = Vertex()
17        childVertex.key = key
18        
19        
20        //add the vertex to the graph canvas
21        canvas.append(childVertex)        
22        
23        return childVertex
24    }
25}

تابع addEdge دو رأس دریافت می‌کند که به نام مبدأ و همسایه شناخته می‌شوند. از آنجا که مدل ما به صورت پیش‌فرض یک گراف جهت‌دار است، یک یال جدید ایجاد می‌شود و به فهرست همسایگی رأس مبدأ تنظیم می‌شود. برای یک گراف غیر جهت‌دار یک یال اضافی ایجاد شده و به رأس همسایگی اضافه می‌شود.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۲ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
swift-algorithms-data-structures
نظر شما چیست؟

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