1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
public class CompositeVolume : Volume { private readonly Random Random = new Random(); public override Collection<Volume> Subvolumes // stub { get; set; } public override float Capacity // stub { get; } // this is the interesting part: public override Vec GetRandomPosition () { if (Subvolumes.Count == 0) { return null; } else { float sum = 0f; Dictionary<Volume, float> map = new Dictionary<Volume, float> (); foreach (Volume v in Subvolumes) { sum += v.Capacity; map[v] = sum; } float select = (float) Random.NextDouble () * sum; Volume inner = map.First (pair => pair.Value >= select).Key; return inner.GetRandomPosition (); } } }
Refactorings
No refactoring yet !
rikkus
May 7, 2009, May 07, 2009 15:38, permalink
The easiest way to choose a random subvolume would probably be as shown. Also note that I don't recognise Random.NextDouble() - In .NET that's not a static method, for good reason: You generally have to initialise a Random object with a seed before using it.
1
Subvolumes.Skip(random.Next(Subvolumes.Count)).First()
Volume is an abstract geometrical object. It contains a capacity.
CompositeVolume implements Volume. It contains a list of subvolumes.
I want to find a random position inside a CompositeVolume. Depending on the size of each subvolume I select one of them (bigger => higher probability), and let it select a random position in itself.
I'm pretty satisfied with the code as it stands, but since I'm new to C# and especially to .net 3.5, I wondered how it could be improved. I'm open for all suggestions. :)
Edit:
- "Random" is actually a static member of the class. I added it to the code. Sorry about that.
- Simply selecing a random entry in the list is not possible, because I want to take the Capacity property into consideration. Given two Subvolumes with Capacity 1.f and 2.f, the latter should be selected twice as often.