Randomize Data C#

Hey Guys,
I have a Tree of Points that I want to populate with A,B,C & D.
for the given length of branch I calculate percent of points that each of these letters will be placed on.
where for each A, it places 1 A , for each B, it places 3 B, for each C it places 2 C & for each D it places 3 D for the length of each branch.

the issue I have is that instead of generating random order per branch, it is simply assigning the same randomness to all the branches. Here is the Code:

private void RunScript(DataTree<Point3d> x, List<string> inputText, ref object A, ref object B)
  {

    DataTree<Point3d> randomPts = new DataTree<Point3d>();

    DataTree<string> allitemID = new DataTree<string>();

    int j = 0;
    
    List<string> randomizedText = Randomize(inputText);    

    foreach(var branch in x.Branches)
    {
      List<string> itemID = new List<string>();

      int totalCount = branch.Count;  //Incase of List
      int actualdCount = RoundPercentageToInt(totalCount, 0.20, 3); //represents d input
      int actualcCount = RoundPercentageToInt(totalCount, 0.30, 2); //represents c input
      int actualbCount = RoundPercentageToInt(totalCount, 0.20, 3); //represents b input
      int actualaCount = totalCount - (actualbCount + actualcCount + actualdCount); //represents a input

      


      foreach(var text in randomizedText)
      {

        if(text == "A")
        {
          for(int i = 0; i < actualaCount; i++)
          {
            itemID.Add(text);
          }
        }
        else if(text == "B")
        {
          for(int i = 0; i < actualbCount; i++)
          {
            itemID.Add(text);
          }
        }
        else if(text == "C")
        {
          for(int i = 0; i < actualcCount; i++)
          {
            itemID.Add(text);
          }
        }
        else
        {
          for(int i = 0; i < actualdCount; i++)
          {
            itemID.Add(text);
          }
        }

      }
      allitemID.AddRange(itemID, new GH_Path(j));

      randomPts.AddRange(branch, new GH_Path(j));
      j++;
    }


    A = randomPts;
    B = allitemID;






  }

  // <Custom additional code> 



  public int RoundPercentageToInt(int dividend, double percent, int divisor)
  {
    int roundtoInt;

    int dCount = (int) (dividend * percent);

    if (dCount % divisor == 0)
    {
      roundtoInt = dCount;

    }
    else
    {
      if(dCount % divisor > 1)
      {
        roundtoInt = dCount + 1;
      }
      else
      {
        roundtoInt = dCount - dCount % divisor;
      }
    }
    return roundtoInt;
  }

  //Randomise a list

  public List<string> Randomize(List<string> list)
  {
    List<string> randomizedList = new List<string>();
    while (list.Count > 0)
    {
      Random iRandom = new Random();
      int index = iRandom.Next(0, list.Count); //pick a random item from the master list
      randomizedList.Add(list[index]); //place it at the end of the randomized list
      list.RemoveAt(index);
    }
    return randomizedList;
  }

Any Idea what might be the mistake.
Thanks.Random Placement with Count.gh (11.8 KB)

You’re using the same list of randomized text for each branch — I think you meant to randomize the list differently for each branch. I’m not sure this is exactly what you were after but it does generate different values per branch. It’s important to know that the Random class will always generate the same sequence unless you give it a different seed value.

Random Placement with Count.gh (15.4 KB)

Thanks @andheum, Yes. That works.

It’s important to know that the Random class will always generate the same sequence unless you give it a different seed value.

Thanks for the clarification. :ok_hand:

@andheum following the same concept on DataTree, and with given condition of percentage of each strings to be populated, I prepared the Code

private void RunScript(DataTree<Point3d> pts, List<string> inputText, List<double> percent, ref object A)
  {

    int totalCount = pts.DataCount;  //Total Point Count in pts

    //Calculate the percentage of each text type for totalCount
    int actualdCount = RoundPercentageToInt(totalCount, percent[0], 3); //represents d input
    int actualcCount = RoundPercentageToInt(totalCount, percent[1], 2); //represents c input
    int actualbCount = RoundPercentageToInt(totalCount, percent[2], 3); //represents b input
    int actualaCount = totalCount - (actualbCount + actualcCount + actualdCount); //represents a input

    Print("required Count of D: " + actualdCount.ToString());
    Print("required Count of C: " + actualcCount.ToString());
    Print("required Count of B: " + actualbCount.ToString());
    Print("required Count of A: " + actualaCount.ToString());

    Print("//--------//");

    List<string> dList = new List<string>();
    List<string> cList = new List<string>();
    List<string> bList = new List<string>();
    List<string> aList = new List<string>();


    DataTree<string> allText = new DataTree<string>();



    for(int k = 0; k < pts.BranchCount; k++)
    {
      int j = 0;
      var branch = pts.Branches[k];
      var path = pts.Paths[k];
      for (int i = 0; i < branch.Count; i += j)
      {
        //m is a persistent int;
        string randomID = PickRandom(inputText, m);

        if(randomID == "D")
        {
          j += 3;
          if(i + j < branch.Count)
          {
            if(dList.Count < actualdCount)
            {
              for (int d = 0; d < 3; d++)
              {
                dList.Add(randomID);
                allText.Add(randomID, path);
              }
            }

          }
        }

        else if(randomID == "B")
        {
          j += 3;
          if(bList.Count < actualbCount)
          {
            if(i + j < branch.Count)
            {
              for (int b = 0; b < 3; b++)
              {
                bList.Add(randomID);
                allText.Add(randomID, path);
              }
            }

          }
        }
        else if(randomID == "C")
        {
          j += 2;
          if(cList.Count < actualcCount)
          {
            if(i + j < branch.Count)
            {
              for (int c = 0; c < 2; c++)
              {
                cList.Add(randomID);
                allText.Add(randomID, path);
              }
            }

          }
        }
        else if(randomID == "A")
        {
          j += 1;
          if(aList.Count < actualaCount)
          {
            for (int a = 0; a < 1; a++)
            {
              aList.Add(randomID);
              allText.Add(randomID, path);
            }

          }
        }
      }
      m++;
    }

    Print("Achieved Count of D: " + dList.Count.ToString());
    Print("Achieved Count of C: " + cList.Count.ToString());
    Print("Achieved Count of B: " + bList.Count.ToString());
    Print("Achieved Count of A: " + aList.Count.ToString());



    A = allText;



  }

  // <Custom additional code> 
  int m;

  public string PickRandom(List<string> myStrings, int seed)
  {
    Random random = new Random(seed);
    int randomIndex = random.Next(myStrings.Count);

    return myStrings[randomIndex];
  }

  public int RoundPercentageToInt(int dividend, double percent, int divisor)
  {
    int roundtoInt;

    int dCount = (int) (dividend * percent / 100);

    if (dCount % divisor == 0)
    {
      roundtoInt = dCount;

    }
    else
    {
      if(dCount % divisor > 1)
      {
        roundtoInt = dCount + 1;
      }
      else
      {
        roundtoInt = dCount - dCount % divisor;
      }
    }
    return roundtoInt;
  }

But for Some reason I dont get the correct output, see here:


You will notice that first on the “Out” panel required and achieved counts don’t match.
The loop should run till all the Counts are matched.

What could I be missing here?
Randomize DataTree with Specific percentage of Counts.gh (12.8 KB)

I found the error. All I had to do was add another counter as persistent integer and put ‘m’ inside the code with initialized value .

For those interested here is the solution