
SimPy (উচ্চারণ 'Blimpie'-এর মতো) হলো প্রক্রিয়া-ভিত্তিক ডিসক্রিট-ইভেন্ট সিমুলেশনের জন্য একটি পাইথন প্যাকেজ।
ইনস্টলেশন
SimPy ইনস্টল করার সবচেয়ে সহজ উপায় হলো pip ব্যবহার:
pip install simpy
আউটপুট এমন কিছু দেখতে পাবেন:

লেখার সময় simpy-3.0.11 সর্বশেষ সংস্করণ, এবং নিচের সব উদাহরণে এটিই ব্যবহার করা হয়েছে।
যদি SimPy ইতিমধ্যে ইনস্টল করা থাকে, আপগ্রেডের জন্য pip-এর সাথে --U অপশন ব্যবহার করুন:
pip install --U simpy
দ্রষ্টব্য: পাইথন ২.৭ বা উচ্চতর সংস্করণ থাকতে হবে এবং লিনাক্স/ইউনিক্স/ম্যাকওএস-এ SimPy ইনস্টল করতে রুট প্রিভিলেজ দরকার হতে পারে।
SimPy সফলভাবে ইনস্টল হয়েছে কিনা চেক করতে একটি পাইথন শেল খুলুন এবং import simpy লিখুন।
মৌলিক ধারণাগুলো
SimPy হলো একটি ডিসক্রিট-ইভেন্ট সিমুলেশন লাইব্রেরি। SimPy-এর সক্রিয় উপাদানগুলো (যেমন: বার্তা, যানবাহন বা গ্রাহক) প্রক্রিয়া (process) দিয়ে মডেল করা হয়। SimPy-এ সক্রিয় エンটিটিগুলোকে প্রক্রিয়া বলা হয়। একটি প্রক্রিয়া হলো একটি পাইথন জেনারেটর যা ডিসক্রিট ইভেন্টগুলি yield করে। মনে রাখবেন, আমি কিছু রিটার্ন করছি না কিন্তু yield করছি, এটিই সাধারণ ফাংশন এবং জেনারেটরের পার্থক্য। এটি আমাদের ইভেন্ট তৈরি করতে এবং সেগুলোকে ট্রিগার হওয়ার জন্য অপেক্ষা করতে yield করতে দেয়।
যখন একটি প্রক্রিয়া একটি ইভেন্ট yield করে, প্রক্রিয়াটি সাসপেন্ড হয়ে যায়। SimPy আমাদের সাসপেন্ড করা প্রক্রিয়াটি পুনরায় শুরু করতে দেয় যখন ইভেন্টটি ট্রিগার হয়। যদি একাধিক প্রক্রিয়া একই ইভেন্টের জন্য অপেক্ষা করে, SimPy সেগুলোকে যেই ক্রমে তারা সেই ইভেন্টটি yield করেছিলো সেই ক্রমেই পুনরায় শুরু করে।
def gen(x): y = yield x+1 return y
>>> g = gen(1) >>> next(g) 2 >>> next(g) Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> next(g) StopIteration
উপরের ইটারেশন ভেরিয়েবল x প্রথম yield করার পর থেমে যায়।
Timeout টাইপের ইভেন্টগুলো একটি নির্দিষ্ট পরিমাণ (সিমুলেটেড) সময় পাস করার পর ট্রিগার হয়। Timeout ইভেন্ট একটি প্রক্রিয়াকে নির্দিষ্ট সময় ধরে রাখতে বা স্লিপ করতে দেয়। Environment-এর উপযুক্ত মেথড কল করে Timeout সহ সকল ইভেন্ট তৈরি করা যায় যেখানে প্রক্রিয়াটি বাস করে।
# গুরুত্বপূর্ণ লাইব্রেরি ইম্পোর্ট from random import randint import simpy # কনফিগারেশন TALKS_PER_SESSION = 3 TALK_LENGTH = 30 BREAK_LENGTH = 15 ATTENDEES = 1 def attendee(env, name, knowledge=0, hunger=0): talks = 0 breaks = 0 # সেশনগুলো পুনরাবৃত্তি while True: # টক들에 যোগদান for i in range(TALKS_PER_SESSION): print('Talk {0} begins at {1}'.format(talks+1, env.now)) knowledge += randint(0, 3) / (1 + hunger) hunger += randint(1, 4) talks += 1 yield env.timeout(TALK_LENGTH) print(f'Talk {talks} ends at {env.now}') print('Attendee %s finished talks with knowledge %.2f and hunger %.2f' % (name, knowledge, hunger)) # বিরাম নিন, বাফেটে যান food = randint(3, 12) hunger -= min(food, hunger) yield env.timeout(BREAK_LENGTH) print('Attendee %s finished eating with hunger %.2f' % (name, hunger)) # সিমুলেশন চালান env = simpy.Environment() for i in range(ATTENDEES): env.process(attendee(env, i)) env.run(until=250)
উপরের প্রোগ্রামটি রান করলে আউটপুট এমন কিছু হবে:

এখানে আমরা একটি কনফারেন্স হলের পরিস্থিতি অনুকরণ করার চেষ্টা করেছি, যেখানে র্যান্ডম সংখ্যক স্পিকার আছে, প্রতি সেশনে ৩টি টক, টকের দৈর্ঘ্য ৩০ মিনিট এবং বিরামের দৈর্ঘ্য ১৫ মিনিট।
আমাদের attendee প্রক্রিয়াটি নতুন ইভেন্ট তৈরি করতে একটি Environment (env), নাম, knowledge এবং hunger-এর রেফারেন্স নেয়। সেশনগুলো মিথ্যা হওয়া পর্যন্ত অসীম লুপে চলবে। attendee() ফাংশনটি একটি জেনারেটর যা টার্মিনেট হবে না কিন্তু yield স্টেটমেন্ট পাওয়ার সাথে সাথে কন্ট্রোল ফ্লো সিমুলেশনের কাছে ফিরিয়ে দেবে।
শেষে, আমরা একটি ডেমো সিমুলেশন 'conference attendee' ২৫০ মান পর্যন্ত চালাই (এতে রয়েছে- ৩টি টক, ১টি বিরাম, ৩টি টক, ১টি বিরাম, ১টি টক)।