mercredi 20 juillet 2016

DIstribute any ammount of elements in a matrix of any size

This is more of a reflexion than a question per se since I could solve this with code but I think there should be better ways of doing this.

I need to distribute elements in a matrix so that each quadrant of the matrix (which dimensions aren't necessarily divisible by 4) contains an equal (or as close to equal as possible) number of said elements but is located randomly within that quadrant. The rest of the matrix needs to contain random elements of a different type.

For instance, distributing 10 elements (A) in a 9x6 matrix could look like this:

enter image description here

Which reveals the problem of what to do with the middle lines when a dimension is odd. It could be included on one quadrant or the other randomly (the fact that there are no As in the 3 middle columns is just chance)

I first thought of dealing with this with a recursive function that divides into quadrants and randomly places each element.

I'm halfway through coding this in C#, the idea being something like this (it doesn't work as of yet and some things are inefficient to try to make the code more readable):

private void PopulateQuadrants(ref Test5Target[,] matrix,
        int xBeginQuadrant, int xEndQuadrant, int yBeginQuadrant, int yEndQuadrant, int targets)
    {
        if (targets == 0)
        {
            return;
        }
        else if (targets == 1)
        {
            Random rand = new Random();
            matrix[rand.Next(xBeginQuadrant, xEndQuadrant), rand.Next(yBeginQuadrant, yEndQuadrant)]
                = new Test5Target(ChosenTarget, UseAdvancedTargets);
            for (int x = xBeginQuadrant; x < xEndQuadrant; x++)
            {
                for (int y = xBeginQuadrant; y < xEndQuadrant; y++)
                {
                    if (matrix[x, y] == null)
                    {
                        int type = rand.Next(TargetCount);
                        while(type == ChosenTarget){
                            type = rand.Next(TargetCount);
                        }

                        matrix[x, y] = new Test5Target(rand.Next(TargetCount), UseAdvancedTargets);
                    }
                }
            }

            return;
        }
        else
        {
            int[] TargetsPerQuadrant = { targets / 4, targets / 4, targets / 4, targets / 4 };
            int RemaindingTargets = targets % 4;
            Random rand = new Random();
            while (RemaindingTargets > 0)
            { // Randomly select quadrants to allocate the Remainding targets (one may end up with 3 extra as it is now)
                TargetsPerQuadrant[rand.Next(4)]++;
                RemaindingTargets--;
            }
            PopulateQuadrants(ref matrix, xBeginQuadrant, xEndQuadrant / 2, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[0]);
            PopulateQuadrants(ref matrix, xEndQuadrant / 2, xEndQuadrant, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[1]);
            PopulateQuadrants(ref matrix, xBeginQuadrant, xEndQuadrant / 2, yBeginQuadrant, yEndQuadrant / 2, TargetsPerQuadrant[2]);
            PopulateQuadrants(ref matrix, xEndQuadrant / 2, xEndQuadrant, yBeginQuadrant / 2, yEndQuadrant, TargetsPerQuadrant[3]);
        }
    }

Is there any mathmatically correct or simple or something way of achieving this or should I keep going in this way.




Aucun commentaire:

Enregistrer un commentaire