[Решено]Оптимальное заполнение площади.[Алгоритм][C#]

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by BrainDeaD, 22 Mar 2011.

  1. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    Есть площадь определённого размера XY.
    Имеется определённое кол-во N элементов с неизвестными размерами AB. (все элементы одинаковы.)

    Задача найти AB так, что-бы площадь была оптимально заполнена элементами. Тоесть как можно меньше свободного места оставалось на площади. Елементы не должны выходить за границы площади.

    Некую роль здесь играет ориентация расположения. Для примера возьмём горизонтальную. Расположение решёткой.

    Вроде бы ничего не забыл. Если что - спрашивайте.
    Надеюсь на вашу помощь.
     
  2. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Если всё площади и фигуры имеют прямоугольную форму, то
    1) S1 = X * Y; - узнаешь площадь общую
    2) S2 = целое(S1 / N); - узнаешь максимальный размер площади фигуры
    3) Далее надо решить систему уровнений типа

    а) A*B стремится к S2
    б) A * Z1 стремится к X
    в) B * Z2 стремится к Y
    г) Z1 * Z2 стремится к N

    По правилам - система может быть решена если кол-во неизвестных = кол-во уравнений. так что скорее всего норм будет.

    Самая сложность в решении, что значение должно стремиться к нужному числу, по этому надо тока перебором
     
    1 person likes this.
  3. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    Спасибо Слешик. Чтото подобное у меня тоже получилось, но меня смутил перебор. Так как это явно математическая задача, надеялся, что существует готовый упрощённый алгоритм. Весь гугл перекопал, но ничего не нашёл, т.к. точно не знаю, по каким ключевым словам искать.

    Ну что-ж придётся решать так.
     
  4. Spot

    Spot Elder - Старейшина

    Joined:
    1 Mar 2007
    Messages:
    461
    Likes Received:
    38
    Reputations:
    1
    Интересно

    Не по поводу твоей задачи, однако, тема довольно интересно, о размещении максимального количества предметов на определённой площаде(в определённом обьеме),
    а хабре мелькал интересный Тыц .
    Статья довольно познавательная, возможно решение пригодиться в дальнейшем.

    ЗЫ, обрати внимание на коммент el777 и прилагаемую ссылку.
     
  5. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    774
    Likes Received:
    292
    Reputations:
    214
    Всем спасибо!

    Зделал так. (элементы в форме квадрата)
    Код комментировать некогда, сорри.

    Code:
    private void ReorderElements()
    {
    	int controlCount = this.Controls.Count;
    	if (controlCount < 1)
    		return;
    
    	int approxElementArea = (this.Width * this.Height) / controlCount;
    	int approxElementSide = (int)Math.Sqrt(approxElementArea);
    
    	while (this.ElementCount(approxElementSide) < controlCount)
    	{
    		approxElementSide--;
    	}
    
    	Size еlementItemSize = new Size(approxElementSide, approxElementSide);
    	Point[] elementPosition = this.CalculateElementPositions(
                              approxElementSide, this.rowCount, this.columnCount);
    
    	for (int i = 0; i<controlCount; i++)
    	{
    		this.Controls[i].Size = elementItemSize;
    		this.Controls[i].Location = elementPosition[i];
    	}
    }
    
    Code:
    private int ElementCount(int approxElementSide)
    {
    	columnCount = this.Width / approxElementSide;
    	rowCount = this.Height / approxElementSide;
    
    	return columnCount*rowCount;
    }
    
    Code:
    private Point[] CalculateElementPositions(int approxElementSide, int rowCount, int columnCount)
    {
    	Point[] elementPoints = new Point[columnCount * rowCount];
    	int x = 0, y = 0, k = 0;
    
    	if (verticalElementOrientation)
    	{
    		for (int cols = 0; cols < columnCount; cols++)
    		{
    			y = 0;
    			for (int rows = 0; rows < rowCount; rows++)
    			{
    				еlementPoints[k++] = new Point(x, y);
    				y += approxElementSide;
    			}
    			x += approxElementSide;
    		}
    	}
    
    	else
    	{
    		for (int rows = 0; rows < rowCount; rows++)
    		{
    			x = 0;
    			for (int cols = 0; cols < columnCount; cols++)
    			{
    				еlementPoints[k++] = new Point(x, y);
    				x += approxElementSide;
    			}
    			y += approxElementSide;
    		}
    	}
    	return elementPoints;
    }