Couper des bâtons égaux de différents bâtons


10

Vous avez n bâtons de longueurs arbitraires, pas nécessairement intégrales.

En coupant quelques bâtons (une coupe coupe un bâton, mais nous pouvons couper aussi souvent que nous le voulons), vous voulez obtenir k<n bâtons tels que:

  • Tous ces k bâtons ont la même longueur;
  • Tous les k sticks sont au moins aussi longs que tous les autres sticks.

Notez que nous obtenons n+C bâtons après avoir effectué des coupes C

Quel algorithme utiliseriez-vous pour que le nombre de coupes nécessaires soit minimal? Et quel est ce nombre?

À titre d'exemple, prenons k=2 et tout n2 . L'algorithme suivant peut être utilisé:

  • Ordonner les bâtons par ordre décroissant de longueur tel que L1L2Ln .
  • Si L12L2 couper le bâton # 1 en deux morceaux égaux. Il y a maintenant deux bâtons de longueur L1/2 , qui sont au moins aussi longtemps que les bâtonnets restants 2n .
  • Sinon ( L1<2L2 ), coupez le bâton # 1 en deux morceaux inégaux de tailles L2 et . Il y a maintenant deux bâtons de longueur , qui est plus longue que et les autres bâtons .L 2 L 1 - L 2 3 nL1L2L2L1L23n

Dans les deux cas, une seule coupe suffit.

J'ai essayé de généraliser cela à un plus grand , mais il semble y avoir beaucoup de cas à considérer. Pouvez-vous trouver une solution élégante?k

Réponses:


6

La première observation fondamentale pour résoudre ce problème est que la faisabilité d'une longueur de coupe ,l

,Feasible(l)=[i=1nLilk]

est constante par morceaux, continue à gauche et non croissante en . Étant donné que le nombre de coupes nécessaires se comporte de manière similaire, trouver la longueur optimale est justel

.l=max{lFeasible(l)}

De plus, comme les autres réponses l'ont proposé, toutes les discontinuités de saut ont la forme . Cela nous laisse avec un problème de recherche unidimensionnel discret susceptible de recherche binaire (après avoir trié un ensemble fini de candidats).Li/j

Notez en outre que nous devons seulement considérer les qui sont plus courts que le k-plus grand, car celui-ci est toujours faisable.Lik

Ensuite, différentes bornes sur conduisent à des algorithmes d'efficacité différente.j

  • donne un espace de recherche de taille quadratique (en k ),1jkk
  • dans une représentation linéaireithmique (en supposant que les L i sont triés par taille décroissante), et1jk/iLi
  • limites légèrement plus impliquées dans une limite linéaire.

En utilisant cela, nous pouvons résoudre le problème proposé dans le temps et l'espace Θ ( n + k ) .Θ(n+klogk)Θ(n+k)

Une autre observation est que la somme de augmente de 1 par 1 pour chaque candidat L i / j "passé", en comptant les doublons. En utilisant cela, nous pouvons utiliser la sélection de rang au lieu de la recherche binaire et obtenir un algorithme qui s'exécute dans le temps et l'espace Θ ( n ) , ce qui est optimal.Feasiblel1Li/jΘ(n)

Trouvez les détails dans notre article Algorithmes efficaces pour une division de bâton sans envie avec moins de coupes (par Reitzig et Wild, 2015).


Il se trouve que les idées de notre approche de la coupe des bâtons se répercutent sur le problème plus général ou la répartition (proportionnelle) , un problème de pertinence pratique; voir notre court article à ce sujet .
Raphael

4

Comme l'a suggéré @randomA, nous procéderons en deux phases: nous trouverons d'abord l'ensemble des bâtons qui seront coupés puis minimiserons le nombre de coupes.

Comme dans le cas particulier de la question, on trie / nomme les bâtons de sorte que . Cela prend du temps O ( n log n ) .L1L2LnO(nJournaln)

Comme l'a souligné @ user1990169, nous n'avons jamais à couper un morceau .jek

Dans la première phase, nous utilisons une recherche binaire pour trouver le nombre , 1 s k , de sorte que les bâtons 1 , , s peuvent être coupés en au moinss1sk1,,s morceaux de taille L s (plus quelques petits morceaux), mais les bâtonnets 1 , , s - 1 ne peuvent pas être coupés en k morceaux de taille L s - 1 . Cela prendra du temps O ( k log k ) .kLs1,,s-1kLs-1O(kJournalk)

Si , cette valeur est la taille optimale et nous pouvons sauter la phase deux.Ls-1=Ls

Sinon, nous savons que la taille optimale satisfait L s - 1 > o L s et si o > L s alors o résulte de la coupe d'au moins un des bâtons en morceaux de taille égale. La phase deux déterminera o :oLs-1>oLso>Lsoo

Pour chaque bâton , 1 i s , déterminez un ensemble de tailles candidates comme suit: Si la découpe en morceaux de taille L s transforme le bâton en morceaux r i (y compris le plus court, le cas échéant), alors les candidats pour ce bâton sont toutes les valeurs L ije1jesLsrje , oùjrietLiLjejjrje. (Voirla réponse de @ user1990169pour savoir pourquoi ce sont les seules tailles candidates.)Ljej<Ls-1

Conservez pour chaque taille de candidat, combien de fois cela s'est produit. En utilisant un arbre de recherche équilibré, cela peut être fait dans , car le nombre total de tailles candidates est lié par i r i2 k .O(kJournalk)jerje2k

Maintenant, la taille candidate qui s'est produite le plus souvent et conduit à une coupe valide est celle qui nous donne la solution optimale. En outre, si une taille candidate conduit à une coupe valide, toute taille plus petite entraînera également une coupe valide.

Nous pouvons donc à nouveau utiliser la recherche binaire pour trouver la plus grande longueur candidate qui mène à une coupe valide dans . Ensuite, nous itérons sur l'ensemble des longueurs candidates jusqu'à ce seuil et trouvons celui avec la plus grande multitude parmi eux dans O ( k ) .O(kJournalk)O(k)

Au total, nous obtenons un runtime en , ou O ( k log k ) , si nous ignorons (ou n'avons pas à le faire) le tri initial.O(nJournaln)O(kJournalk)


Dans l'étape de recherche binaire, comment vérifiez-vous exactement si "les bâtons peuvent être coupés en au moins1,,s morceaux de taille L s "? kLs
Erel Segal-Halevi

Pour calculer L i1jes . La somme de ces valeurs est le nombre de pièces que vous pouvez obtenir. Lje/Ls
FrankW

"la taille du candidat qui s'est produite le plus souvent ... est celle qui nous donne la solution optimale" - pourquoi?
Erel Segal-Halevi

Parce que chaque fois que cela se produit, nous avons un bâton qui donne morceaux avec t - 1 coupes. tt1
FrankW

1
Le nombre total de coupes est dans le meilleur des cas (kk2 bâtons de longueur égale, tous les autres bâtons au plus moitié moins longtemps que ceux-ci et autant que je sache ne seront jamais plus quek-k2 . (Il ne sera certainement jamais supérieur à k , car chaque coupe donne un bâton de la bonne longueur et un reste. Mais il semble que nous pouvons toujours choisir une taille afin qu'au moins une coupe laisse un reste de la bonne longueur. Je ne mais je n'ai pas de preuve pour ça.)k-1k
FrankW

1

Après avoir commandé les bâtons dans l'ordre décroissant de leur longueur, un bâton ne sera coupé que si tous les bâtons L 1Lje a été coupé.L1,L2,...Lje-1

Maintenant que , nous ne ferons aucune coupe sur les bâtonsk<n , car nous pouvons toujours avoir k bâtons de longueur L k .LkkLk

Alors maintenant, au lieu de , nous avons affaire à seulement kn sticks (en ajoutant éventuellement le k -th stick dans son ensemble), et le nombre maximum de coupes qui seront nécessaires dans le pire des cas = k - 1 .k-1k=k-1

De plus, si le nombre optimal de coupes est , alors il doit y avoir au moins un ensemble de bâtons parmi ces k - 1 bâtons qui doivent être pris dans leur ensemble à partir de 1 bâton d'origine<k-1k-1(soit en parties ou en 1 pièce) , c'est-à-dire qu'aucune partie de ce bâton d'origine ne doit être laissée «non prise». En effet, selonleprincipe dupigeonnier, il doit y avoir au moins 1 coupe qui doit produire plus d'un bâton valide.

Vous pouvez ensuite effectuer deux boucles imbriquées (les deux jusqu'à ). La boucle extérieure doit indiquer le numéro de bâtonk dont toutes les parties doivent être prises et la boucle intérieure doit indiquer le nombre de pièces j constituées de ce bâton. Pour chaque taille L ijej
vérifiez si vous pouvez obtenir des k bâtons réalisables en coupant les bâtonsL1en séquence et si possible, mettez à jour les coupes minimales requises jusqu'à présent si le nombre actuel requis est inférieur.LjejL1

La complexité totale de l'algorithme ci-dessus est O(nlog(n)+k3)


1

L'idée de haut niveau serait la recherche binaire.

La taille de chacun des k bâtons demandés sera au moins le plus petit bâtonnet et au plus le plus gros. Pour cette raison, nous procédons en utilisant une recherche binaire sur la taille du bâton du milieu, voyons quel nombre nous pouvons obtenir, si ce k ' est supérieur au k donné, alors nous savons que nous devons choisir une nouvelle taille de référence candidate. Nous passons donc au plus grand ou au plus petit en utilisant un nouveau bâton de référence. On s'arrête quand k est inférieur à kkkkkk

Une fois que nous avons trouvé le bâton de référence approprié, il y a un cas d'angle où nous aurions besoin d'affiner davantage la taille. Nous pouvons trier tous les bâtons coupés par le nombre de coupes sur eux et la taille du bâton. Choisissez celui avec le moins de coupes et la taille la plus petite. Réduisez le nombre de coupes sur ce bâton de 1 et faites tous les sous-bâtons de cette taille égale. Ce sera la nouvelle taille de référence, vérifiez si cette nouvelle taille peut conduire à une taille acceptable. J'avoue, je ne sais pas comment limiter le temps de course dans ce cas.k

J'espère que je peux voir quelque chose d'utile à partir d'autres réponses.


2
Je pense que l'idée de base de votre approche fonctionnera. Mais votre description de l'algorithme n'est pas suffisamment claire pour être sûre. Pourriez-vous ajouter un pseudocode plus détaillé?
FrankW

@FrankW Je ne suis pas trop sûr du temps de fonctionnement. Je vais voir ce que les autres ont, c'est une question assez intéressante à poser.
Informé le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.