Je suis en train de régler le code de l'wikipedia:algorithme de changement de prise dynamique qui retourne la liste réelle des pièces utilisées
https://en.wikipedia.org/wiki/Change-making_problem#Implementation
Pour aussi sortie la liste des pièces utilisées, non seulement le nombre de pièces de monnaie utilisées. C'est-à-dire, par exemple:
change_making([6, 8, 12], 52)
produit 5
ce qui est correct (12+12+12+8+8 = 52
).
Le problème est que je veux obtenir la sortie dans ce format [12, 12, 12, 8, 8]
au lieu de seulement 5
et je n'ai aucune idée de comment faire cela.
Le code en question:
def _get_change_making_matrix(set_of_coins, r):
m = [[0 for _ in range(r + 1)] for _ in range(len(set_of_coins) + 1)]
for i in range(r + 1):
m[0][i] = i
return m
def change_making(coins, n):
"""This function assumes that all coins are available infinitely.
n is the number that we need to obtain with the fewest number of coins.
coins is a list or tuple with the available denominations."""
m = _get_change_making_matrix(coins, n)
for c in range(1, len(coins) + 1):
for r in range(1, n + 1):
# Just use the coin coins[c - 1].
if coins[c - 1] == r:
m[c][r] = 1
# coins[c - 1] cannot be included.
# We use the previous solution for making r,
# excluding coins[c - 1].
elif coins[c - 1] > r:
m[c][r] = m[c - 1][r]
# We can use coins[c - 1].
# We need to decide which one of the following solutions is the best:
# 1. Using the previous solution for making r (without using coins[c - 1]).
# 2. Using the previous solution for making r - coins[c - 1] (without using coins[c - 1]) plus this 1 extra coin.
else:
m[c][r] = min(m[c - 1][r], 1 + m[c][r - coins[c - 1]])
return m[-1][-1]
Toute aide/suggestion serait grandement appréciée.
------------- ------------- EDIT
La solution (les commentaires supprimés):
def _change_making(coins, n):
m = [[0 for _ in range(n + 1)] for _ in range(len(coins) + 1)]
for i in range(n + 1):
m[0][i] = i
for c in range(1, len(coins) + 1):
for r in range(1, n + 1):
if coins[c - 1] == r:
m[c][r] = 1
elif coins[c - 1] > r:
m[c][r] = m[c - 1][r]
else:
m[c][r] = min(m[c - 1][r], 1 + m[c][r - coins[c - 1]])
i = len(coins)
j = n
ret = {k: 0 for k in coins}
while j != 0:
if m[i][j - coins[i - 1]] == m[i][j] - 1:
ret[coins[i - 1]] += 1
j = j - coins[i - 1]
else:
i = i - 1
return ret
Pour trouver le plus proche * solution:
def change_making(coins, n):
try:
return _generate_packing(coins, n)
except:
return generate_packing(coins, n + 1)
Par exemple change_making([2, 5], 8)
{2: 2, 5: 1}
Parce que 9 est la solution la plus proche possible.
- par le plus proche je veux dire une solution qui est possible de satisfaire mais surtout la demande initiale. Par exemple, si nous devons retourner £ 8 en changement et nous n'avons pas le changement exact, eh bien, nous allons retourner £ 9 parce que nous avons des changements pour cela.
Merci, ça fonctionne parfaitement! Puis-je demander - comment allez-vous ajuster le code pour produire «la solution la plus proche», par ex. 'pièces de monnaie = [6, 8]', 'n = 19'. Évidemment, nous ne pouvons pas créer un nombre impair à partir de nombres pairs. Cependant, nous pouvons faire '6 + 6 + 8' pour' n = 20'. Existe-t-il une approche plus optimale que d'essayer 'n + = 1', 'change_making ([6, 8, 12], n)' jusqu'à ce que nous trouvions une solution possible? – emihir0
dépend de la façon dont «plus proche» de la valeur d'origine, vous avez besoin de votre réponse. Comme pour seulement une différence de 1 vous pouvez: 1) créer la matrice 'm' jusqu'à la plage' m [len (pièces)] [n + 1] '(à l'origine' m [len (pièces)] [n] ') et faire les réglages si nécessaire dans le code. 2) Comparer 'm [len (pièces)] [n + 1]' et 'm [len (pièces)] [n-1]' (comme n = 18 et 20 seront les plus proches) quand somme n n'est pas possible. 3) Réponse de sortie pour le minimum de ces deux. – monster
J'essaie de résoudre un problème similaire, mais le nombre de pièces par type est limité. EX: (1, compte: 10), (2, compte: 5) etc Donc, toute idée que ce qui doit être changé pour lister les pièces de chaque type pour la valeur donnée? – Santhosh