1

I have a List of 10,000 entries of type Element:

public class Element
{
    public Element()
    {
        this.Id = Guid.NewGuid();
    }

    public Guid Id { get; set };
}

And I have another List of 5,000 entries of type Link:

public class Link
{
    public Link(Guid ElementOne, Guid ElementTwo)
    {
        this.ElementOne = ElementOne;
        this.ElementTwo = ElementTwo;
    }

    public Guid ElementOne { get; set; }
    public Guid ElementTwo { get; set; }
}

I am populating my Lists here:

for (int i = 0; i < 10,000; i++)
    this.ListOfElements.Add(new Element());

for (int i = 0; i < 5,000; i++)
{
    this.ListOfLinks.Add(new Link(need ElementOne, need ElementTwo));
}

I am not sure what to pass for ElementOne and ElementTwo. I want to grab a random Id from the Element List (Element.Id) for both parameters and ensure they're unique (ElementOne could never be ElementTwo).

Rufus L
  • 36,127
  • 5
  • 30
  • 43
  • You need to keep track of elements you are adding or quering ListOfLinks everytime you want to add something, and adding a method to give you next one to add – Reza May 11 '18 at 15:47
  • So, can ElementOne and ElementTwo NEVER repeat? Or do you just want to avoid linking 1 - 1. Is linking 1-2 and then 1-3 ok? Do you need to avoid linking 1-2, then later linking 1-2 again? – Tyler Lee May 11 '18 at 15:52
  • Oh sorry, I wasn't clear - I just don't want 1 - 1. 1 - 2 repeated is fine. –  May 11 '18 at 15:53

5 Answers5

2

Sounds like you just need two random numbers. You can compare and repoll if you happen to get a duplicate.

for (int i = 0; i < 5,000; i++)
{
    int ele1 = Random.NextInt(10000);
    int ele2 = Random.NextInt(10000);

    while(ele1 == ele2){
        ele2 = Random.NextInt(10000);
    }
    this.ListOfLinks.Add(new Link(ListOfElements[ele1], ListOfElements[ele2]));
}
Tyler Lee
  • 2,736
  • 13
  • 24
0

The code below will give a random array of the index to your list. So you can take randIndex[0] and randIndex[1] to get two random items.

            Random rand = new Random();
            List<string> myList = new List<string>() { "a","b","c"};
            int[] randIndex = myList.Select((x,i) => new {i = i, rand = rand.Next()}).OrderBy(x => x.rand).Select(x => x.i).ToArray();
jdweng
  • 33,250
  • 2
  • 15
  • 20
-1

You need to find next element which is not used, also using .OrderBy(i => Guid.NewGuid()) to get random element

private Element GetNextAvaibaleElement() {
  var usedElementIds = listOfLinks.Select(i => i.ElementOne).Union(listOfLinks.Select(i => i.ElementTwo));
  return listOfElements.Where(i => !usedElementIds.Contains(i.Id)).OrderBy(i => Guid.NewGuid()).FirstOrDefault();
}

and then get two available elements

for (int i = 0; i < 5,000; i++)
{
    this.ListOfLinks.Add(new Link(GetNextAvaibaleElement().Id,GetNextAvaibaleElement().Id));
}

See this dotnet fiddle here

Reza
  • 18,865
  • 13
  • 88
  • 163
-1

Create an instance of the Random class somewhere.

E.g.

static Random rdm = new Random();

Then, use this rdm instance to generate a random integer, delete that element from the list (so as not to reuse it), and keep going until you deplete your list.

List<Element> listOfElements; // list of 10k Elements

for (int i = 0; i < 5,000; i++)
{
    int r = rdm.Next(listOfElements.Count);
    Element elementOne = listOfElements[r]; 
    listOfElements.RemoveAt(r);
    r = rdm.Next(listOfElements.Count);
    Element elementTwo = listOfElements[r]; 
    this.ListOfLinks.Add(new Link(elementOne, elementTwo));
}
C. Helling
  • 1,394
  • 6
  • 20
  • 34
-1

One approach to solving this is to create a list of integers representing the indexes into the ListOfElements, then order that list in a random way. Then you can simply reference items in the ListOfElements by index, sequentially walking through the randomized index list:

private static void Main()
{
    for (int i = 0; i < 10000; i++) ListOfElements.Add(new Element());

    // Create a randomly-ordered list of indexes to choose from
    var rnd = new Random();
    var randomIndexes = Enumerable.Range(0, ListOfElements.Count)
        .OrderBy(i => rnd.NextDouble()).ToList();

    // Now use our random indexes to pull unique items from the Element list
    for (int i = 0; i < 10000; i += 2)
        ListOfLinks.Add(new Link(ListOfElements[randomIndexes[i]].Id,
            ListOfElements[randomIndexes[i + 1]].Id));

    GetKeyFromUser("\nDone! Press any key to exit...");
}
Rufus L
  • 36,127
  • 5
  • 30
  • 43