Algorithme de Diviser une liste de nombres dans 2 l'égalité de la somme des listes
Il y a une liste de nombres.
La liste est divisée en 2 de taille égale listes, avec une différence minime dans la somme. Les sommes doivent être imprimés.
#Example:
>>>que = [2,3,10,5,8,9,7,3,5,2]
>>>make_teams(que)
27 27
Est-il une erreur dans le code suivant algorithme pour certains cas?
Comment puis-je optimiser et/ou pythonize ce?
def make_teams(que):
que.sort()
if len(que)%2: que.insert(0,0)
t1,t2 = [],[]
while que:
val = (que.pop(), que.pop())
if sum(t1)>sum(t2):
t2.append(val[0])
t1.append(val[1])
else:
t1.append(val[0])
t2.append(val[1])
print min(sum(t1),sum(t2)), max(sum(t1),sum(t2)), "\n"
Question est de http://www.codechef.com/problems/TEAMSEL/
- Est-ce Devoirs?
- est-ce une variante du bin-packing problème? C'est un problème NP-complet de problème, IIRC.
- qc = [1,50,50,100] devrait vous donner équipes de 100 et 101. Je pense que votre algorithme rendement de 51 et 150.
- C'est un problème pratique dans un concours de programmation. Voici la référence: codechef.com/problems/TEAMSEL de Mon mieux comprendre dit, il est de droite. Mais le système marqué cette incorrecte.
- B: Quand j'ai couru, j'ai eu 100 et 101.
- B: je reçois 100 et 101, à juste titre, pour votre entrée.
- regarde ma solution, je pense que vous l'aimerez.
Vous devez vous connecter pour publier un commentaire.
Nouvelle Solution
C'est une vaste recherche d'abord avec l'heuristique de l'abattage. L'arbre est limitée à une profondeur de joueurs/2. Le joueur somme limite est totalscores/2. Avec un joueur de la piscine de 100, il a fallu environ 10 secondes à résoudre.
Aussi noter que j'ai essayé de régler cela à l'aide de GS de la description, mais il est impossible d'obtenir suffisamment d'informations simplement en stockant les totaux en cours d'exécution. Et si vous avez stocké des les deux le nombre d'éléments et les totaux, alors il serait le même que celui de la solution que vous avez gardé inutile de données. Parce que vous avez seulement besoin de garder les n-1 et n itérations jusqu'à numplayers/2.
J'avais un vieux exhaustive basée sur des coefficients binomiaux (voir dans l'histoire). Il a résolu l'exemple des problèmes de longueur 10, mais ensuite j'ai vu que la concurrence y avait des gens de longueur 100.
La programmation dynamique est la solution que vous cherchez.
Exemple avec [4, 3, 10, 3, 2, 5]:
12 est notre nombre de la chance! Backtracing de demander au groupe:
L'autre peut alors être calculé: {4,3,10,3,2,5} - {5,3,4} = {10,3,2}
Tous les champs avec un nombre de solutions sont possibles pour un sac. Choisissez celui qui est le plus éloigné dans le coin en bas à droite.
BTW: Ça s'appelle la sac à dos-problème.
[16, 5, 5, 3, 3]
devrait sortir deux listes de somme16
,[16]
et[5, 5, 3, 3]
. Ta solution me semble de limiter le nombre d'éléments de chaque liste deceil(n/2) = 3
...Bien, vous pouvez trouver une solution à un pourcentage de précision en temps polynomial, mais pour trouver le meilleur (absolue de la différence minime) de la solution, le problème est NP-complet. Cela signifie qu'il n'est pas temps polynomial pour résoudre le problème. Comme un résultat, même avec une petite liste de nombres, c'est trop de calcul intensif à résoudre. Si vous avez vraiment besoin d'une solution, prendre un coup d'oeil à certains des algorithmes d'approximation pour cela.
http://en.wikipedia.org/wiki/Subset_sum_problem
Q. Donné un multiset S d'entiers, est-il un moyen de partition de S en deux sous-ensembles S1 et S2 tels que la somme des nombres dans S1 est égale à la somme des numéros de S2?
A.Définir La Partition De Problème.
Bonne chance à l'approximation. : )
Noter que c'est aussi une heuristique et j'ai déplacé le sortir de la fonction.
C'est en fait une PARTITION, un cas particulier de sac à DOS.
Il est NP Complet, avec des pseudo-polynomial dp algorithmes. Le pseudo en pseudo-polynomial se réfère au fait que le temps d'exécution dépend de la gamme de poids.
En général, vous devrez d'abord décider s'il y a une solution exacte avant de vous peut admettre une solution heuristique.
Un cas de test où votre méthode ne fonctionne pas est
Le problème, c'est que vous êtes analyser les choses en paires, et dans cet exemple, vous souhaitez que tous les 50 à être dans le même groupe. Cela devrait être résolu, si vous retirez la paire analyse de l'aspect et il suffit de faire une entrée à la fois.
Voici le code qui fait ce
Ce qui donne 27, 27 et 150, 1002 qui sont les réponses qui ont du sens pour moi.
Edit: En examen, pour moi c'est pas réellement, mais en fin de compte, je ne suis pas tout à fait sûr pourquoi. Je vais poster mon code de test ici si, comme il pourrait être utile. Le test génère un ordre aléatoire qui ont le même montant, les met ensemble et compare (avec les tristes résultats).
Edit #2: Basé dans l'exemple souligné par des Inconnus,
[87,100,28,67,68,41,67,1]
, il est clair pourquoi ma méthode ne fonctionne pas. Plus précisément, pour résoudre cet exemple, les deux plus grand nombre de besoin à la fois d'être ajouté à la même séquence pour obtenir une solution valide.Ils sont de toute évidence à la recherche pour une programmation dynamique à dos de la solution. Donc, après mon premier effort (une assez bonne d'origine heuristique j'ai pensé), et mon deuxième effort a vraiment sournois exacte combinatoire solution qui a fonctionné pour assez courts ensembles de données, et de même pour les ensembles jusqu'à 100 éléments, tant que le nombre de unique valeurs est faible), J'ai finalement succombé à la pression des pairs et a écrit de celui qu'ils voulaient (pas trop dur de manutention de la duplication d'entrées a été la partie la plus délicate - l'algorithme sous-jacent je me suis basé sur fonctionne seulement si toutes les entrées sont uniques, je suis bien contente que long est assez grand pour contenir 50 bits!).
Donc, pour toutes les données de test et maladroit bord des cas, j'ai mis en place lors des tests de mes deux premiers efforts, il donne la même réponse. Au moins pour ceux que j'ai vérifié avec la combinatoire solveur, je savoir ils sont corrects. Mais je suis encore, à défaut de la présentation avec une certaine mauvaise réponse!
Je ne demande pas de quelqu'un pour corriger mon code ici, mais je serais très reconnaissant si quelqu'un peut trouver un cas pour lequel le code ci-dessous génère la mauvaise réponse.
Merci,
Graham
PS, Ce code ne s'exécute toujours dans la limite de temps, mais il est loin de optimisés. je suis pour garder les choses simples jusqu'à ce qu'elle passe le test, j'ai quelques idées pour l'accélérer, peut-être par un facteur de 10 ou plus.
Pour la performance, vous enregistrez les calculs en remplaçant append() et sum() avec des cumuls.
Vous pourriez vous serrez la boucle d'un peu d'aide suivants:
Depuis les listes doivent me égal, le problème n'est pas NP à tous.
J'ai divisé la liste triée avec le modèle t1<-que(1er, dernier), t2<-que(2e, dernier-1) ...
Modifier: je suppose que c'est aussi une mauvaise méthode. De mauvais résultats!
Après un peu de réflexion, pour ne pas trop gros problème, je pense que le meilleur type d'heuristique sera quelque chose comme:
Vous pouvez ajuster nb_iter si le problème est plus grand.
Il résout tous les problèmes mentionnés ci-dessus la plupart du temps tout le temps.
Dans un précédent commentaire que j'ai supposé que le problème était docile parce qu'ils avaient choisi avec soin les données de test pour être compatible avec les différents algorithmes dans le temps imparti. Cela s'est avéré ne pas être le cas -, c'est plutôt le problème des contraintes - les numéros de pas de supérieure à 450 et un ensemble final pas plus de 50 numéros est la clé. Celles-ci sont compatibles avec la résolution du problème à l'aide de la programmation dynamique la solution, j'ai mis dans un post plus tard. Aucun des autres algorithmes heuristiques, ou énumération exhaustive par une combinatoire de pattern generator) peuvent éventuellement travailler parce qu'il y aura des cas de test assez grand ou assez dur à briser ces algorithmes. C'est plutôt ennuyeux pour être honnête, car les autres solutions sont plus difficiles et certainement plus de plaisir. Notez que sans beaucoup de travail supplémentaire, la programmation dynamique solution juste dit que si une solution est possible avec N/2 pour une somme donnée, mais elle ne vous dit pas le contenu de la partition.