1 Востаннє редагувалося FakiNyan (01.12.2014 19:16:57)

Тема: Допоможіть реалізувати частинку алгоритму

Хайо. Щось моя мозкова активність взагалі впала до нуля, сьогодні. Зовсім не можу сконцентруватись.
Дивіться, що тре зробити.
Уявімо, що є масив з людьми.
Кожна людина має певне значення, котре може бути в діапазоні від 0 до 1.
Якщо додати ці значення усіх людей, то вийде рівно 1.
Далі нам треба крутнути лотерейку, котра дає нам випадкове число від 0 до 1.
Після того, як ми отримали це число, ми дивимось, в яку людину (умовно кажучи) ми потрапили.
Робиться то от таким чином.
Нехай, у нас є 3 людини. Перша людина має значення 0.2, друга - 0.3, а третя - 0.5.
А лотерея дала нам число 0.4.
І от ми будуємо таку штуку

Прихований текст

http://не-дійсний-домен/dcQFU/3bd1d9c759.png

Таким чином ми відібрали людину під номером два.
І от нам треба відібрати 3 ПАРИ людей, при чому можуть бути от такі пари
{{1,2},{2,1},{3,2}}
повторень, типу {{1,3},{1,3},{2,3}}
бути не може, і зрозуміло, що {1,1} теж бути не може.
Яким чином це все краще реалізувати?
А то як тільки в мене з'являється ідея, то я розумію, що вона не задовольняє якомусь правилу, і мій мозок перезавантажується, і я так сижу і дуже довго туплю.
От мій варіант, його вада в тому, що в множені пар може існувати дві ідентичні пари, а ще буває таке, що пара складається лишень з одної людини. Я то наче і розумію, чому таке стається, але при думці, як то виправити, з'являються лишень одні костилі.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace testConsole
{
    class Program
    {
        class unit
        {
            public double fitness;
            public int value;

            public unit(double fitness, int value)
            {
                this.fitness = fitness;
                this.value = value;
            }
        }
        static void Main(string[] args)
        {
            List<unit> units = new List<unit>();
            units.Add(new unit(0.2,1));
            units.Add(new unit(0.3, 2));
            units.Add(new unit(0.5, 3));

            Random rand = new Random();
            foreach (var unit in units)
            {
                List<unit> parents=new List<unit>();
                for (int i = 0; i < 2; i++)
                {
                    double tempRand = rand.NextDouble();
                    double summ = 0;

                    foreach (var unit1 in units)
                    {
                        summ += unit1.fitness;
                        if (summ > tempRand && !parents.Contains(unit1))
                        {
                            parents.Add(unit1);
                            break;
                        }
                    }
                }

                foreach (var parent in parents)
                {
                    Console.Write(parent.value+" ");
                }
                Console.WriteLine();
            }
            Console.ReadKey();
        }
    }
}

2

Re: Допоможіть реалізувати частинку алгоритму

Ви написали, як вибиратете випадково людину, але не написали як вибираєте пару.

3 Востаннє редагувалося FakiNyan (01.12.2014 19:23:47)

Re: Допоможіть реалізувати частинку алгоритму

Vo_Vik написав:

Ви написали, як вибиратете випадково людину, але не написали як вибираєте пару.

 List<unit> parents=new List<unit>(); // ліст з парою
                for (int i = 0; i < 2; i++) // для вибору пари
                {
                    double tempRand = rand.NextDouble();
                    double summ = 0;
 
                    foreach (var unit1 in units)
                    {
                        summ += unit1.fitness;
                        if (summ > tempRand && !parents.Contains(unit1)) // як тільки знайшли юніта, котрий виграв лотерею, і котрого немає в масиві з майбутньою парою
                        {
                            parents.Add(unit1);// додаємо його в масив з парою, майбутньою
                            break; // заново
                        }
                    }
                }

Біда в тому, що лотерея може потрапити в останнього по рахунку юніта, і після цього вже ніхто в пару не обирається.

4

Re: Допоможіть реалізувати частинку алгоритму

Такс, мені ніколи панькатись з цими алгоритмами, тому я пішов прямо! Замінив

for (int i =0 ; i<2; i++)

на

 while(parents.Count<2)

Ну а що? Рано чи пізно відшукаємо потрібний юніт, ліл.

5

Re: Допоможіть реалізувати частинку алгоритму

власне, я пішов тим самим шляхом і з перевіркою, чи існує відібрана пара у множині всіх пар. Якщо не існує - шукаємо нову, і так доти, доки не знайдемо нову унікальну пару

6

Re: Допоможіть реалізувати частинку алгоритму

той, тему можете закривати