Go Dilinde Asansör Yönetim Sistemi Simülasyonu

Mehmet Ali Mergen
Developer Community
4 min readAug 30, 2023

Asansörlerin çalışma ve karar mekanizması her zaman beni meraklandırmıştır. Özellikle çok kabinli asansör sistemlerinde, hangi kabinin nereye yönlendirileceğine karar verilirken birden fazla koşulun değerlendirilip en uygun kararın alınması gerektiği bir gerçek. Peki, bu karmaşık karar sürecinde neler rol oynuyor hiç düşündünüz mü? Bu blog yazısında, asansörlerin hareketlerini belirlemek için kullanılan koşulları ve yöntemleri derinlemesine ele alacağız. Hadi başlayalım.

Bölümler:

1-) Temel Yapılar ve Veri Modelleri
2-) Kontrol Paneli Oluşturma
3-) Asansör Çağırma
4-) Asansör Hareketi Yönetimi
5-) Simülasyonu Çalıştırma
6-) Log izleme
7-) Toparlama
8-) Kaynak Kodlar

1-) Temel Yapılar ve Veri Modelleri

type (
Elevator struct {
Capacity int // maksimum kişi sayısı
InstantPeople int // anlık kaç kişi taşıyor
InstantFloor int // anlık kat bilgisi
Direction string // "up", "down", "none"
CabineId int // kabin kimlik bilgisi
}

ControlPanel struct {
Elevators []Elevator // asansör yapıları
TotalFloor int // binanın sahip olduğu kat sayısı
}
)

Bu yapılar, asansör sisteminin temel bileşenlerini ve önemli verilerini organize etmek için kullanılıyor. Her bir asansör ve kontrol paneli örneği, sistemin belirli bir durumunu temsil ederken, bu veri modelleri sayesinde sistemin genel yapısını anlamak ve yönetmek daha anlaşılır oluyor.

2-) Kontrol Paneli Oluşturma

İkincil olarak Singleton Design Pattern yaklaşımını benimseyerek Control Panel örneğimizi oluşturalım. (Asansör bilgileri karışık verilmiştir. İstediğiniz şekilde değiştirebilirsiniz)


var ControlPanelInstance *ControlPanel
var controlPanelOnce sync.Once
var mu sync.Mutex // Mutex for protecting ControlPanelInstance

func GetControlPanel() *ControlPanel {
controlPanelOnce.Do(func() {
ControlPanelInstance = &ControlPanel{
Elevators: []Elevator{
Elevator{
Capacity: 12,
InstantPeople: 3,
InstantFloor: 1,
Direction: "up",
CabineId: 1,
},
Elevator{
Capacity: 12,
InstantPeople: 0,
InstantFloor: 2,
Direction: "none",
CabineId: 2,
},
Elevator{
Capacity: 12,
InstantPeople: 9,
InstantFloor: 3,
Direction: "down",
CabineId: 3,
},
},
TotalFloor: 11,
}
})
return ControlPanelInstance
}

Burda yapmış olduğumuz iş; asansör kontrol sisteminin başlatılmasını ve kontrol panelinin oluşturulmasını sağlar. GetControlPanel fonksiyonu, ControlPanelInstance adında bir örnek oluşturur veya mevcut örneği döndürür. Bu örnek, asansörlerin özelliklerini ve kontrol panelinin toplam kat sayısını içerir. Kod içindeki sync.Once yapıları sayesinde kontrol paneli yalnızca bir kez oluşturulur ve sync.Mutex kullanılarak eşzamanlı erişim engellenir. Bu sayede asansörlerin başlangıç durumları belirlenir ve kontrol paneli hazır hale getirilir.

3-) Asansör Çağırma

func CallElevator(currentFloor, personCount int, direction string) *Elevator {
mu.Lock()
defer mu.Unlock()

var closestElevator *Elevator
shortestDistance := 1000 // A large initial value

for i, elevator := range ControlPanelInstance.Elevators {
if (elevator.Direction == "none" || elevator.Direction == direction) && elevator.InstantPeople+personCount <= elevator.Capacity {
distance := abs(currentFloor - elevator.InstantFloor)
if distance < shortestDistance {
closestElevator = &ControlPanelInstance.Elevators[i]
shortestDistance = distance
}
}
}

return closestElevator
}

CallElevatorfonksiyonu, bir asansör çağrısını simüle ediyor. Mevcut kat, kişi sayısı ve yön bilgisini alarak en uygun asansörü seçmeye çalışır. İşlev, mevcut asansör durumlarını değerlendirir ve uygun koşullar sağlandığında en yakın asansörü seçer. Seçilen asansörün referansını döndürür ve bu şekilde çağrının hangi asansör tarafından karşılanacağı belirlenir. Eğer uygun bir asansör bulunmazsa, nil döner.

4-) Asansör Hareketi Yönetimi

func ElevatorMoveManagement(elevator *Elevator) {
mu.Lock()
defer mu.Unlock()

if elevator.Direction == "none" {
fmt.Printf("Elevator %d is not moving.\n", elevator.CabineId)
return
}

fmt.Printf("Elevator %d is moving %s from floor %d\n", elevator.CabineId, elevator.Direction, elevator.InstantFloor)

var startFloor, endFloor int
if elevator.Direction == "up" {
startFloor = elevator.InstantFloor + 1
endFloor = ControlPanelInstance.TotalFloor
} else {
startFloor = elevator.InstantFloor - 1
endFloor = 0
}

for floor := startFloor; floor != endFloor; {
elevator.InstantFloor = floor
fmt.Printf("Elevator %d is on floor %d with %d people\n", elevator.CabineId, elevator.InstantFloor, elevator.InstantPeople)
time.Sleep(time.Second) // Simulate time passing

if elevator.Direction == "up" {
floor++
} else {
floor--
}
}

fmt.Printf("Elevator %d has reached its destination.\n", elevator.CabineId)
elevator.Direction = "none"
}

ElevatorMoveManagementfonksiyonu, bir asansörün hareketini yönetir. Parametre olan asansör referansını alarak, asansörün hareket etmesi gereken durumları ele alır. Eğer asansör hareket etmiyorsa, hareketsiz olduğunu belirtir ve işlev sona erer. Hareket ediyorsa, yön ve kat bilgilerini ekrana yazar. Hedef kata ulaşıncaya kadar asansörün durumunu güncelleyerek ve geçen zamanı simüle ederek ilerler. Hedefe ulaşıldığında yine ekrana bilgi yazar ve asansörün yönünü “none” olarak günceller, çünkü hedefe varılmıştır. Bu işlev, asansörlerin belirli bir yön ve hedefe göre hareket etme simülasyonunu gerçekleştirir.

5-) Simülasyonu Çalıştırma

func main() {
// Initialize elevator instances
GetControlPanel()

// Run the ElevatorMoveManagement for each elevator to simulate their movement
for i := range ControlPanelInstance.Elevators {
go ElevatorMoveManagement(&ControlPanelInstance.Elevators[i])
}

go SimulateElevatorTransaction()

// Keep the main thread running
select {}
}

main içinde simülasyon başlatılır. Asansörlerin hareketini simüle etmek için ElevatorMoveManagement methodu gorutin olarak çalıştırılır. Aynı zamanda insanların asansörlere binip inme işlemleri de SimulateElevatorTransaction (Kaynak repodan bu methoda erişebilirsiniz) işlevi ile simüle edilir. Bu bir sonsüz döngü ile kendini tekrar eder.

6-) Log izleme

Eee o kadar kod yazdık logları incelemeyelim mi? Bu noktadan sonra incelemezsek zaten boynu bükük kalırdı kodlarımızın 😂😂

Hyper terminal üzerinde log takibi
Docker Desktop üzerinden log takibi

7-) Toparlama

Sonuç olarak, Golang ile geliştirdiğimiz bu asansör yönetim sistemi simülasyonu, birden fazla kabinli asansörlerin etkileşimini ve yönetimini anlamamıza yardımcı oluyor. Veri modelleri ve işlevler sayesinde asansörlerin durumları, insanların talepleri ve yönlendirmeleri takip edilebiliyor. Bu kod örneği, asansör sistemlerinin karmaşıklığını ve yönetiminin nasıl yapılabileceğini metinsel bir şekilde anlamamıza olanak tanıyor. Simülasyonlar, gerçek dünya senaryolarının anlaşılmasını kolaylaştırmak ve bu tür sistemlerin test edilmesini sağlamak için önemli bir araç olabilir.

--

--