Taille maximale du carré pour un nombre inconnu à l'intérieur du rectangle
Si j'ai un jeu de tuiles (carrés), qui peut être n'importe quel nombre et ils sont à remplir un récipient (rectangle) d'une taille inconnue comment puis-je travailler sur la taille maximale des carreaux sans avoir un quelconque d'entre eux se chevauchent.
Donc, si j'ai 2 carreaux et le rectangle est de 100 * 100, puis le max taille du carreau est de 50 * 50. Ce serait aussi le max de la taille de la tuile, si il n'y avait 3 ou 4 tuiles pour cette taille de rectanlgle, qui se trouve juste à être un carré dans cet exemple.
Si le rectanlge était de 100 * 30 et j'ai eu 2 tuiles, la taille maximale de la place serait de 30 * 30, si j'ai 4 carreaux de la taille maximale de 25 * 25.
Comment puis-je le faire par programmation, sans accaparer le processeur en passant par toutes les combinaisons possibles.
J'ai essayer de résumer un peu mieux,
J'ai un:
rectangle/boîte englobante que je dois remplir, autant que possible, sans les tuiles superposées.
Je sais que la hauteur et la largeur du rectangle (mais cela peut changer au cours de l'exécution).
J'ai X nombre de tuiles (cela peut changer au moment de l'exécution), ce sont des carrés.
Aucun des tuiles doivent se chevaucher, ce qui est la taille maximale que chaque tuile peut être. Ils sont tous de la même taille.
source d'informationauteur kenneth
Vous devez vous connecter pour publier un commentaire.
Sur le plan conceptuel:
de la place dans votre boîte de grille, jusqu'à présent, de réduire les
la boîte existante juste assez pour faire
la salle de ligne ou de colonne.
pseudo: compte tenu de M x N rectangle à remplir avec K carrés
Il y a probablement plus rapide des moyens de saut à la réponse à la très grande K, mais je ne peux pas penser à eux. Si vous savez que M et N sont des nombres entiers, il y a peut être encore des méthodes plus rapides.
C'est un emballage de problème. Les solutions optimales sont difficiles à trouver. Voir, par exemple,L'emballage de N carrés dans un carré.
Vous pouvez calculer une (optimiste) limite supérieure en divisant la surface totale par le nombre de carrés:
sqrt(width*height/n)
.Ici est un O(1) solution sans boucles.
En utilisant le rapport d'aspect (hauteur/largeur) du rectangle, vous pouvez venir avec un premier deviner le nombre de tuiles dans les directions x et y. Cela donne une limite supérieure et limite inférieure pour le nombre total de carreaux: entre xy et x+1)(y+1).
Sur la base de ces limites, il y a trois possibilités:
J'ai testé cette fonction, pour tout entier largeurs, hauteurs et tileCounts entre 1 et 1000 en utilisant le code suivant:
J'ai réussi à venir avec un "relativement" solution optimale. Basée en partie sur la Zac du pseudo-code de réponse.
Ce que cela fait, c'est de travailler sur la superficie totale de la rectanlge, puis le diviser par le nombre de carreaux. Comme chaque tuile est un carré, je peux SQRT ceci afin de tirer le maximum de la taille optimale de la tuile.
Avec cette taille optimale je vérifie pour voir combien d'ENSEMBLE de tuiles que je peux tenir dans la largeur & de la hauteur. Multiplier ces ensemble et si c'est moins que le nombre requis de carreaux puis-je réduire la taille optimale et assurer la vérification de nouveau jusqu'à ce que toutes les tuiles ajuster le rectanlge.
Je pourrais optimiser encore plus loin en faisant quelque chose comme réduire la taille optimale par -2 insted de -1 à chaque fois et puis si toutes les tuiles ajustement en hausse de 1 juste pour s'assurer que je n'ai pas manqué une taille valide. ou je pourrais revenir plus de -2, disons -10 ensuite si ils ont toutes les tuiles fit augmenter de 5, puis de si le ne correspondent pas à réduire de -2 etc jusqu'à ce que je obtenir un ajustement optimal.
Découvrez http://kennethsutherland.com/flex/stackover/SlideSorterOK.html pour mon exemple.
Merci pour toutes les infos.
La fonction suivante calcule le maximum de la taille de la tuile de l'information donnée.
Si le fait qu'il est écrit en Python, il est difficile pour vous de comprendre, laissez-moi savoir dans un commentaire et je vais essayer de le faire dans une autre langue.
L'algorithme peut vaguement être décrite comme suit
tiles_max_height
dans le code).C'est probablement l'un des algorithmes plus rapides énumérés ici, car il calcule le meilleur carré de la taille en O(sqrt(n)) pour n tuiles.
Mise à jour
Nouvel examen de la question, ce problème a une solution plus simple basé sur la solution ci-dessus. Dites que vous êtes compte tenu de 30 tuiles. Votre possible tuile arrangements sont faciles à calculer:
Dire que votre rectangle est de 100 x 60. Votre rectangle de rapport d'aspect est 1.6667. C'est entre 1,2 et 2. Maintenant, vous avez seulement besoin de calculer la tuile dimensions de 8 x 4 et 6 x 5 arrangements.
Le premier pas toujours techniquement prend O(sqrt(n)), donc cette mise à jour de la méthode n'est pas asymptotiquement plus rapide que la première tentative.
Quelques mises à jour à partir des commentaires fil
Pourriez-vous élaborer sur la façon de définir le remplir? Si je suis votre description (un grand "si") il semble que la plupart des cas que vous décrivez ne fait pas de remplir le rectangle. Par exemple, dites-vous 2 cases en 100*100 rectangle serait de 50*50. Si je comprends votre configuration correctement, ils seraient placés sur la "diagonale" de ce rectangle. Mais alors il y aurait deux "trous" de la taille 50*50 dans ce rectangle. Ce n'est pas ce que je pense de "combler" le rectangle. Je serais à la place de l'état le problème que ce est la plus grande taille possible pour 2 (de taille égale carrés) dont la boîte englobante serait de 100*100 (en supposant que chaque carré a dû être en contact avec au moins une autre place?).
Le point clé ici est que votre rectangle semble être une boîte englobante n'est pas rempli.
Aussi, pouvez-vous écrire une interface fonctionnelle pour ce calcul? Avez-vous besoin de le faire pour n possible, les places étant donné les dimensions de la boîte englobante?
Donné des valeurs:
côté d'un carreau peut être calculée à l'aide de cette fonction:
j'ai supposé que vous n'allez pas faire des carreaux plus petits que 1x1, quelle que soit la mesure de 1 est
d'abord, vous commencez à partir de la taille 0:
ensuite, vous parcourez de 1 à K colonnes de tuiles où
pour chaque itération calculer la nouvelle valeur maximale côté d'un carreau à l'aide de cette formule
cette formule prend la plus petite de ces deux valeurs:
si le candidat newL est supérieure à la valeur initiale l et un maximum de tuiles qui peuvent être mis en place sans la superposition est plus grand ou égal que le nombre de carreaux de n puis
sur la fin retour l
Je suppose que les places ne peuvent pas être tournés. Je suis assez sûr que le problème est très difficile si vous êtes autorisé à faire pivoter.
Afin de nous remplir le rectangle par des places en commençant dans le coin haut-gauche. Ensuite, nous avons mis les carrés à droite de cette place jusqu'à ce que nous atteignons le côté droit du rectangle, puis nous faisons la même chose avec la ligne suivante jusqu'à ce que nous arrivons à la partie inférieure. C'est comme l'écriture d'un texte sur le papier.
Observer qu'il n'y aura jamais une situation où il y a de l'espace à gauche sur le côté droit et sur le fond. Si il y a de l'espace dans les deux directions, puis on peut toujours augmenter la taille des carrés.
Supposons que nous savons déjà que 10 places doit être placé sur la première ligne, et que cela correspond à la largeur de la perfection. Ensuite, la longueur du côté est
width/10
. On peut donc mettrem = height/sidelength
places dans la première colonne. Cette formule pourrait dire que l'on peut placer 2.33 places dans la première colonne. Il n'est pas possible de placer 0.33 d'un carré, on ne peut placer 2 places. La vraie formule estm = floor(height/sidelength)
.Un pas très rapide (mais BEAUCOUP plus rapide que d'essayer chaque combinaison de l'algorithme est d'essayer pour la première place 1 place sur la première ligne/colonne, puis voir si nous pouvons les placer assez de places dans le rectangle. Si cela ne fonctionne pas, nous essayons de 2 cases sur la première ligne/colonne, etc. jusqu'à ce que nous pouvons adapter le nombre de tuiles que vous voulez.
Je pense qu'il existe un algorithme O(1) si vous êtes autorisé à faire des opérations en O(1), mais je n'ai pas compris jusqu'à présent.
Voici une version de Ruby de cet algorithme. Cet algorithme est O(sqrt (nombre de tuiles)) si le rectangle n'est pas très mince.
Vous pouvez également utiliser les binaires de recherche pour cet algorithme. Dans ce cas, il est en O(log (n ° de tuiles)).
Diviser le côté le plus long par le nombre de tuiles. Utiliser le côté le plus petit que la taille de la tuile. Presto! # de tuiles.