2012-12-23 6 views
4

내가 5 개 결과 나는 무작위 그렇게 가중치가 100무작위로 가중치와 행동을 할

그것을 무작위로 인쇄 시작 말할 수 가중치를 사용하여 위의 작업 중 하나를 수행 할

Console.WriteLine("1"); 
Console.WriteLine("2"); 
Console.WriteLine("3"); 
Console.WriteLine("4"); 
Console.WriteLine("5"); 

이 있다고 할 수 있습니다 1이고 그 무게를 5로 내림으로써 무게를 내림 95.

이렇게하면 오름차순으로 가중치가 (95, 100, 100, 100, 100)이므로 100 개의 모든 가중치는 5 %의 확률을 갖습니다. 무작위로 95 점 이상을 선택했지만 95 점은 무작위로 선택 될 확률이 높지만 다른 사람들만큼이나.

샘플 출력 (콘솔 출력)

1 (weight = 95) 
3 (weight = 95) 
1 (weight = 90) 
5 (weight = 95) 
1 (weight = 85) 
2 (weight = 95) 
+3

[무엇을 시도해 봤습니까?] (http://whathaveyoutried.com) –

+2

원하는 출력을 표시 할 수 있습니까? 내가 이해할 수 없다 –

+1

난 그냥 무작위 계량 알고리즘을 구현하는 몇 가지 코드를 썼습니다 1-5도, 그래서 귀하의 코드를 확인해야합니다. – PeterJ

답변

1

에 의해 그 무게를 줄일 :

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<ActionWithChance> list = new List<ActionWithChance>() 
              { 
               new ActionWithChance("1", 100), 
               new ActionWithChance("2", 100), 
               new ActionWithChance("3", 100), 
               new ActionWithChance("4", 100), 
               new ActionWithChance("5", 100) 
              }; 

     for (int i = 0; i < 10; i++) 
     { 
      RandomHandler.CreateIntervals(list); 
      RandomHandler.GetRandom(list); 
     } 


    } 
} 

static class RandomHandler 
{ 
    public static void CreateIntervals(List<ActionWithChance> list) 
    { 
     int currentBorderMin = 1; 
     int currentBorderMax = 0; 
     foreach (var actionWithChance in list) 
     { 
      actionWithChance.TempMin = currentBorderMin; 
      actionWithChance.TempMax = currentBorderMax 
           + actionWithChance.Chance; 

      currentBorderMax = actionWithChance.TempMax; 
      currentBorderMin = currentBorderMax; 
     } 
    } 

    public static void GetRandom(List<ActionWithChance> list) 
    { 
     Thread.Sleep(20); 
     int allChance = list.Sum(i => i.Chance); 
     Random rand = new Random(); 
     int nextValue = rand.Next(1, allChance + 1); 
     ActionWithChance selectedAction = 
list.FirstOrDefault(i => i.TempMin <= nextValue && i.TempMax >= nextValue); 

     selectedAction.Chance = selectedAction.Chance > 5 
      ? selectedAction.Chance - 5 : 100; 

     selectedAction.DoSomething(); 
    } 
} 

class ActionWithChance 
{ 
    public string Name { get; set; } 
    public int Chance { get; set; } 
    public int TempMin { get; set; } 
    public int TempMax { get; set; } 

    public void DoSomething() 
    { 
     Console.WriteLine(Name); 
    } 


    public ActionWithChance(string name, int chance) 
    { 
     Name = name; 
     Chance = chance; 
    } 
} 
+1

매 반복마다 새로운 랜덤을 생성하지 않는 것이 좋습니다. 그러나 그것과는 별도로, 내가 너무 게으른 것을 코딩했습니다. :-) – Carson63000

+0

그래, 지루해했다 :) 그러나 그것을 자유롭게해라. –

+0

list.FirstOrDefault 및 list.sum은 System.Collections.Generic에 아이디어가 없습니다. –

2

중첩 된 case 문으로 장난 할 이유가 없습니다 생각.

새 임의 번호를 생성 할 때마다 가중치를 더하십시오.

그런 다음 Random.Next(sumOfWeights)을 사용하십시오.

그런 다음 리턴 된 난수를 첫 번째 가중치, 첫 번째 두 가중치의 합계, 첫 번째 세 가중치의 합계 등과 비교할 때까지 비교하십시오.

선택 사항입니다. 내가 잘 이해한다면, 당신은 출발점으로, 이것을 사용할 수 있습니다 당신이 필요, 다음은 간단한 코드는 5

+0

새 임의 번호를 생성 할 때마다 가중치를 다시 계산하지 않아도됩니다. 개별 무게를 업데이트하는 데 사용 된 것과 동일한 값으로 이전 합계를 업데이트하면됩니다. – Trisped

0

또 다른 방법 :

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

namespace RandomWeights 
{ 
    public class WeightedItem 
    { 
     public string Text { get; set; } 
     public int Weight { get; set; } 

     public WeightedItem(string text, int weight) 
     { 
      Text = text; 
      Weight = weight; 
     } 
    } 
    public class WeightedOutput 
    { 
     public static readonly int _decreaseIncrement = 5; 
     List<WeightedItem> items = new System.Collections.Generic.List<WeightedItem>(); 

     public WeightedOutput() 
     { 
      //initialize the five items with weight = 100 
      for (int i = 1; i <= 5; i++) 
       items.Add(new WeightedItem(i.ToString(), 100)); 

      for (int x = 0; x < 50; x++) 
       WriteSelected(); 

      Console.ReadLine(); 
     } 

     public void WriteSelected() 
     { 
      WeightedItem selectedItem = GetItem(); 
      if (selectedItem != null) 
       Console.WriteLine(selectedItem.Text + ": " + selectedItem.Weight); 
      else 
       Console.WriteLine("All items have 0 probability of getting selected"); 
     } 

     public WeightedItem GetItem() 
     { 
      int totalWeight = items.Sum(x=>x.Weight); 
      Random rnd = new Random((int)DateTime.Now.Ticks); 
      int random = rnd.Next(0, totalWeight); 

      WeightedItem selected = null; 
      foreach (var item in items) 
      { 
       if (random < item.Weight && item.Weight > 0) 
       { 
        //need a new item and not a reference to get the right weights 
        selected = new WeightedItem(item.Text, item.Weight); 
        //decrease item's weight 
        item.Weight -= _decreaseIncrement; 
        break; 
       } 

       random -= item.Weight; 
      } 
      return selected; 
     } 
    } 
}