PDA

View Full Version : گفتگو: به نظر شما چطوری قرعه کشی انجام دهیم که امتیاز افراد نیز مد نظر قرار گیرد؟



ali_najari
یک شنبه 10 بهمن 1389, 22:45 عصر
سلا دوستان:

سوالی داشتم خواستم نظر بقیه دوستان رو بدونم راجعه به اینکه چطوری باید یک سیستم قرعه کشی درست کرد که وابسته به امتیاز افراد باشه؟ بهترین روش از نظر شما چی هست؟

به عنوان مثال اگر توجه کنید که بانکها بر اساس امتیاز افراد قرعه کشی میکنن! در این صورت هر فرد یک امتیازی داره که باید در قرعه کشی دخالت داده شود.


روشی که الان توی ذهن من هست رو تشریح میکنم و ممنون میشم اگر دوستان نظر خودشون رو هم بگن:

به فرض مثال من 5 نفر دارم که A1,A2,A3,A4,A5 آنها را نام گذاری میکنم توی این مثال و امتیازات آنها به شرح زیر هست:

A1 = 30
A2 = 20
A3 = 40
A4 = 500
A5 = 30

حال روشی که من میخواهم استفاده کنم بدین صورت است که ابتدا میام به تعداد امتیازی که افراد دارن اسمهای آنها را در یک لیست اضافه میکنم به عنوان مثال A1 که دارای 30 امتیاز هست را 30 بار در لیست اضافه میکنم. سپس بعد از اضافه شدن همه افراد بصورت رندم افراد را در یک لیست دیگر قرار میدهم.

بعد از اینکه اینکار تمام شد قرعه کشی رو انجام میدم و هنگامی که یک نفر اسمش در قرعه مشخص شد کلیه ردیف هایی که مربوط به آن هست را از جدول دوم حذف میکنم تا دیگر نام آن نیاید و این کار را تا زمانی انجام میدهم که آخرین نفر هم اسمشان در بیاید.

یکی از معایب این راه اینه که هنگامی که تعداد افراد و امتیازها زیاد بشه حجم محاسبه زیادی را باید سیستم انجام بده (تعداد رکوردهای زیادی را در 2 لیست مربوطه باید اضافه کنه)

حال کسی روشی در نظر داره یا درباره این راه کسی تغییری واسه بهتر شدنش داره؟

ali_najari
دوشنبه 11 بهمن 1389, 16:48 عصر
دوستان كسي نظري نداره يا راهي نداره؟

ali_najari
سه شنبه 12 بهمن 1389, 14:44 عصر
دوستان اگر نظری دارن یا راهی بلد هستن بگن خواهشا

ممنون میشم

Help me...

ali_najari
پنج شنبه 14 بهمن 1389, 23:48 عصر
دوستان یعنی واقعا کسی نظری در این رابطه نداره؟

nahidkh
سه شنبه 19 بهمن 1389, 08:25 صبح
با سلام من این نظر رو براتون mail کردم:
یک راه بهینه برای انجام قرعه کشی با امتیاز میتونه به این صورت باشه:
برای هر فرد علاوه بر فیلد امتیاز دو تا فیلد دیگه در نظر می‌گیریم از این قرار: "از امتیاز" و "تا امتیاز"
یک curor باز می‌کنیم و داخل یک حلقه همه‌ی رکوردها رو پردازش می‌کنیم و این دو تا فیلد رو براشون پر می‌کنیم.
در پایان اون حلقه ما رکوردهایی شبیه به این در پایگاه خواهیم داشت:


مشتری امتیاز از امتیاز تا امتیاز
=================================
یک 30 1 30
دو 10 31 41
سه 15 42 57

حالا بزرگترین امتیازی که داریم 57 هست. یک عدد رندوم بین 1 تا 57 انتخاب می‌کنیم و در مرحله‌ی با یک query شبیه به این برنده رو پیدا می‌کنیم
SELECT ID FROM CUSTOMERS WHERE FROM_SCORE >= @RANDOM AND TO_SCORE <+ @RANDOM

ali_najari
سه شنبه 19 بهمن 1389, 21:36 عصر
دوست عزیز میشه لطف کنید و یکم بیشتر راجع به این روش توضیح دهید یا اگر امکان داره یک Sample واسم بزارید؟

Navid Asadi
سه شنبه 19 بهمن 1389, 22:05 عصر
نظر من اینه
فرض کنیم A1 دارای امتیاز 50 هستش عدد 1 تا 50 رو به اون بده
A2 امتیاز 200 رو داره 51 تا 200 رو به اون بده به این ترتیب بدون نایز به لیست میتونی انتخاب تصادفی رو انجام بدی!

saber187518
سه شنبه 19 بهمن 1389, 23:08 عصر
با سلام
دوست عزیز فکر کنم الگوریتم FCFS در سیستم عامل بتونه کمکت کنه.
این الگوریتم به جز کارهای ابتدایی که همه میدونن و برای کار شما مهم نیست و حتی بیخودیه. یه قسمت داره که بهش میگن اولویت
یعنی اینکه با اینکه نوبت به یک نفر میرسه ولی چون نفر دیگه ای هست که اولویت بالاتری داره میتونه سرویس بگیره.
حالا پیشنهاد:
به نظر من بیا و از بین افرادی که قراره قرعه کشی کنی ( البته قبلن اونها رو با یک الگوریتم درهم ریزی کاملا نامرتب کن ) بعد بیا و از این لیست مثلا 10 نفر رو انتخاب کن و
اونی که بالاترین امتیاز رو در این بین داره انتخاب کن.:قهقهه:خودمم به این الگوریتم خندم میاد.
ولی خوب ایده بود که به ذهنم اومد...
موفق باشی

nahidkh
چهارشنبه 20 بهمن 1389, 12:00 عصر
آقای نجاری با چه زبانی و چه بانک اطلاعاتی برنامه می‌نویسین؟

ali_najari
چهارشنبه 20 بهمن 1389, 17:41 عصر
دوست عزیز من میخوام روند قرعه کشی به هیچ عنوان با بانک اطلاعاتی کارب نداشته باشه:

ببینید من توسط بانک اطلاعاتی (که در حال حاضر Access هست دارم برنامه رو مینویسم که در آینده نه چندان دور تمام اطلاعات را به SQL منتقل میکنم) امتیازات مشتریان را توسط یک Query دریافت میکنم از بعد از دریافت اطلاعات نمیخوام دیگه عملیاتی را در بانک انجام بدم و میخوام تمام این عملیات در دل خود برنامه انجام گیرد

paladin
پنج شنبه 21 بهمن 1389, 05:15 صبح
یه راه اینه که به جای اینکه از یه عدد استفاده کنب دو عدد رندوم استفاده کنی یکی شماره مشتری دوم حد اقل امتیاز برای شرکت در این مرحله از قرعه کشی . شماره مشتری ثابت نیست و در هر مرحله با توجه به تعداد شرکت کنندگان تغییر میکنه . حداقل امتیاز دارای یه حد بالا و پایین است . در هر مرحله ضریبی که حد پایین رو مشخص میکنه رو افزایش می دیم که تا امتیازات پایین بخت کمتری برای شرکت داشته باشند( و یا در مراحل بالاتر اصلا شرکت نکنند ) اگه لازمه بیشتر توضیح بدم

ali_najari
پنج شنبه 21 بهمن 1389, 09:54 صبح
یه راه اینه که به جای اینکه از یه عدد استفاده کنب دو عدد رندوم استفاده کنی یکی شماره مشتری دوم حد اقل امتیاز برای شرکت در این مرحله از قرعه کشی . شماره مشتری ثابت نیست و در هر مرحله با توجه به تعداد شرکت کنندگان تغییر میکنه . حداقل امتیاز دارای یه حد بالا و پایین است . در هر مرحله ضریبی که حد پایین رو مشخص میکنه رو افزایش می دیم که تا امتیازات پایین بخت کمتری برای شرکت داشته باشند( و یا در مراحل بالاتر اصلا شرکت نکنند ) اگه لازمه بیشتر توضیح بدم

دوست عزيز درصورت امكان يك مثال عددي بزاريد ممنون ميشم

nahidkh
شنبه 23 بهمن 1389, 10:59 صبح
دوست عزیز من میخوام روند قرعه کشی به هیچ عنوان با بانک اطلاعاتی کارب نداشته باشه:

ببینید من توسط بانک اطلاعاتی (که در حال حاضر Access هست دارم برنامه رو مینویسم که در آینده نه چندان دور تمام اطلاعات را به SQL منتقل میکنم) امتیازات مشتریان را توسط یک Query دریافت میکنم از بعد از دریافت اطلاعات نمیخوام دیگه عملیاتی را در بانک انجام بدم و میخوام تمام این عملیات در دل خود برنامه انجام گیرد

سلام
در اینصورت شما باید یک لیست از آبجکتهای مقیم در حافظه بسازید و روی اون عملیات قرعه کشی رو انجام بدید.
با فرض اینکه شما از #C استفاده می‌کنید و با آبجکتهای عادی ADO کد شما باید شبیه به این باشه:
در قطعه کد مربوط به خواندن رکوردها من فرض می‌کنم که شما متد ExecuteReader رو از SqlCommand یا معادل اون برای هر پایگاه داده‌ی دیگه اجرا کردید و یک آبجکت SqlReader یا معادل اون رو در اختیار دارید.
در خط آخر winnerId حاوی ID برنده است. برای تعداد برنده های بیشتر باید دو خط آخر رو به تعداد دلخواه تکرار کنید.

// کلاس کمکی برای قرعه کشی
public class LotteryAux
{
public int MemberId {get;set;}
public int ScoreFrom {get;set;}
public int ScoreTo {get;set;}
}


// قطعه کد مربوط به خواندن رکوردهای پایگاه داده
SqlConnection connection = new SqlConnection("Connection string");
SqlCommand cmd = conn.CreateComamnd();
cmd.CommandText = "SELECT [Id], [Score] FROM [Members]";
connection.Open();
SqlReader reader = command.ExecuteReader(); List<LotteryAux> auxList = new List<LotteryAux>();
int scoreCounter = 0;
while(reader.read())
{
LotteryAux aux = new LotteryAux();
aux.MemberId = (int) reader["Id"];
aux.ScoreFrom = score + 1;
score += (int) reader["Score"];
aux.ScoreTo = score;
auxList.Add(aux);
}
Random random = new Random();
int winnerScore = rnd.Next(1, score);
int winnerId = auxList.SingleOrDefault(a => a.ScoreFrom >= winnerScore && a.ScoreTo <= score)

nahidkh
شنبه 23 بهمن 1389, 11:10 صبح
دوباره براتون میفرستم

nahidkh
شنبه 23 بهمن 1389, 11:13 صبح
سلام
در اینصورت شما باید یک لیست از آبجکتهای مقیم در حافظه بسازید و روی اون عملیات قرعه کشی رو انجام بدید.
با فرض اینکه شما از #C استفاده می‌کنید و با آبجکتهای عادی ADO کد شما باید شبیه به این باشه:
در قطعه کد مربوط به خواندن رکوردها من فرض می‌کنم که شما متد ExecuteReader رو از SqlCommand یا معادل اون برای هر پایگاه داده‌ی دیگه اجرا کردید و یک آبجکت SqlReader یا معادل اون رو در اختیار دارید.
در خط آخر winnerId حاوی ID برنده است. برای تعداد برنده های بیشتر باید دو خط آخر رو به تعداد دلخواه تکرار کنید.


// کلاس کمکی برای قرعه کشی
public class LotteryAux
{
public int MemberId {get;set;}
public int ScoreFrom {get;set;}
public int ScoreTo {get;set;}
}


// قطعه کد مربوط به خواندن رکوردهای پایگاه داده
SqlConnection connection = new SqlConnection("Connection string");
SqlCommand cmd = conn.CreateComamnd();
cmd.CommandText = "SELECT [Id], [Score] FROM [Members]";
connection.Open();
SqlReader reader = command.ExecuteReader();
List<LotteryAux> auxList = new List<LotteryAux>();
int scoreCounter = 0;
while(reader.read())
{
LotteryAux aux = new LotteryAux();
aux.MemberId = (int) reader["Id"];
aux.ScoreFrom = score + 1;
score += (int) reader["Score"];
aux.ScoreTo = score;
auxList.Add(aux);
}
Random random = new Random();
int winnerScore = rnd.Next(1, score);
int winnerId = auxList.SingleOrDefault(a => a.ScoreFrom >= winnerScore && a.ScoreTo <= score)

nahidkh
شنبه 23 بهمن 1389, 11:21 صبح
براتون mail میکنم نمیدونم چرا اینجا بهم میریزه!

ali_najari
شنبه 23 بهمن 1389, 15:34 عصر
دوست عزیز لطف کنید این قسمت رو واسم توضیح بدید ممنون میشم:


List<LotteryAux> auxList = new List<LotteryAux>();

nahidkh
یک شنبه 24 بهمن 1389, 12:05 عصر
کلاس LotteryAux که قبلاً تعریف شده
قسمتی که گفتید یک لیست پیوندی Generic از نوع LotteryAux ایجاد می‌کنه.
لیست‌های پیوندی Generic مثل لیست‌های معمولی هستند با این تفاوت که اعضای اونها به جای اینکه از نوع object باشند از نوعی هستند که شما بین علامت <> مشخص می‌کنید.

ali_najari
یک شنبه 24 بهمن 1389, 14:32 عصر
سلام دوست عزيز

من اشتباه گذاشتم چيزي كه ميخواستم سوال كنم رو اين رو كه توي پست بالا گذاشتم ميدونم كه براي ايجايد يك ليست از كلاس مربوز هست (List(of LotteryAiux)) مشكل من با مطلب زير هست و اينكه زماني كه دو نفر پيدا بشن با امتياز مساوي كه در اين صورت برنامه خطا ميده:


int winnerId = auxList.SingleOrDefault(a => a.ScoreFrom >= winnerScore && a.ScoreTo <= score)