Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Casse-tête (le retour) Algorithme d'optimisation pour les matheux

9 réponses
Avatar
François Semoulin
Bonjour.

Je suis à la recherche d'un algorithme WD pour réaliser le traitement
suivant:

En quelques mots, je dois trouver un algorithme permettant d'utiliser au
mieux des points de fidélité pour acheter des articles.

Voici l'explication du problème:

Le fichier ARTICLE contient des articles à vendre. Chaque article a un prix
en EURO, un prix en points de fidélité et un nombre de points de fidélité
octroyé à chaque unité vendue de cet article.

Lors de chaque vente, l'acheteur peut payer soit en EURO, soit en points
fidélité qu'il aura collectionné au cours de ses achats précédents.

Le problème est le suivant: Il faut optimiser le paiement en points de
fidélité. En d'autres mots, le logiciel doit spécifier dans la liste des
articles achetés par le client, lesquels il doit payer au moyen de ses
points de fidélité afin de les utiliser au mieux.

L'acheteur remet au vendeur tous ses points de fidélité. Le vendeur encode
dans le programme le nombre de points reçus.

Il faut à ce moment là que le logiciel, sur base des articles sélectionnés
par l'acheteur, optimise au mieux le paiement au moyen des points fidélité
remis, tout en sachant qu'un article ne peut être payé partiellement avec
des points de fidélité.

Exemple:

L'acheteur souhaite acheter les articles suivants:

Qtté Article Prix unitaire EUR Prix unitaire
points fidélité

3 A 2.50? 6pts

1 B 5? 15pts

5 C 0.6? 2pts

Le total de points fidélité nécessaire pour payer cet achat est de 43 (2x6
+1x15 + 5x2).

Imaginons que l'acheteur remette au vendeur 16 points de fidélité.

Question: Comment utiliser au mieux ces points pour payer cet achat?

Dans notre exemple, la meilleure utilisation est:

2xA + 2xC = 2x6 + 2x2 = 16 points, solde de points à utiliser = 0

J'ai déjà consulté les archives du forum et j'ai déjà trouvé la fonction
récursive de Fabrice qui fait cela en partie.

Néanmoins, je pense que ce problème est plus complexe car:

1. Il ne faut pas forcément arriver au nombre de points total à utiliser
mais sans approcher au plus, sans toutefois le dépasser. Ainsi, par exemple,
si l'acheteur remet 30 points au vendeur dans l'exemple cité, je pense que
l'on n'arrive pas à utiliser tous les points remis (30) mais qu'on arrive au
mieux à 29 (1x15 + 2x6 + 1x2). Il faut dans ce cas que le logiciel me sorte
l'utilisation optimale à faire des points tout en indiquant le solde de
points (1 dans ce cas) à rendre à l'acheteur.

2. LA quantité d'articles achetés est limité. On doit donc, à l'inverse du
problème de B. Neve, fixer des limites par article qui sont respectivement
les quantités des divers articles achetés par le client (dans notre exemple
3A, 1B et 5C).

Après avoir bien analysé la fonction récursive de Fabrice, je n'arrive pas à
trouver la solution.

Quelqu'un peut-il me donner un coup de pouce? Je cale...

Merci d'avance et Bonnes fêtes.

François

9 réponses

Avatar
François Semoulin
Bonjour.

Je me réponds suite aux tests que j'ai effectué.

J'ai pondu l'algo suivant:


qttemax est un tableau de 3 entiers
qtteopt est un tableau de 3 entiers
ptsart est un tableau de 3 entiers
ptsremis est un entier
ptsutilises est un entier
solde est un entier
i,j,k est un entier
l,m est un entier long
bsortir est un booleen

qttemax[1]
qttemax[2]0
qttemax[3]P

ptsart[1]=6
ptsart[2]
ptsart[3]=2

ptsremis=saisie1

// On calcule le nombre de points maximum requis
pour i=1 à 3
ptsutilises+=qttemax[i]*ptsart[i]
FIN
// On vérifie si le prix en points de tous les articles achetés est <= au
nombre de points remis
si ptsutilises<ptsremis alors
// C'est le cas, on affecte directement le résultat
pour i=1 à 3
qtteopt[i]=qttemax[i]
FIN
solde=ptsremis-ptsutilises
sinon
// Le nombre de points remis est < au nombre de ponts nécessaire pour
acheter tous les articles
// Il faut donc chercher la meilleure combinaison possible
ptsutilises=0
pour i=0 à qttemax[1]
bsortirúux
pour j=0 à qttemax[2]
bsortirúux
pour k=0 à qttemax[3]
ptsutilises=i*ptsart[1]+j*ptsart[2]+k*ptsart[3]
si ptsutilises>ptsremis alors
bsortir=vrai
sortir
fin
trace(i,j,k,ptsutilises)
l++
si ptsutilises<=ptsremis alors
m++
FIN
fin
si ptsutilises>ptsremis et pas bsortir alors
bsortir=vrai
sortir
fin
fin
si ptsutilises>ptsremis et pas bsortir alors
bsortir=vrai
sortir
fin
FIN
info(l,m)
FIN


Cet algo fonctionne mais il y a, à mes yeux, deux problèmes:
1. Le nombre d'essais pour trouver la solution peut être élevé car, malgré
certains tests, le principe est de tester TOUTES les possibilités!
2. Cet algorithme se limite à trois valeurs de prix par article (ptsart).
Or, dans la réalité, ce nombre n'est pas fixe: il peut être de 1, 2, 3, ...

Quelqu'un peut-il m'aider à résoudre ce problème?
Je ne vois pas de solution pour le 1er problème. Pour le second, il me
semble qu'il faut passer par la récursivité mais je ne m'en sors pas...

Un p'tit coup de main svp...

Merci.

François



"François Semoulin" wrote in message
news:bsbt5e$smu$
Bonjour.

Je suis à la recherche d'un algorithme WD pour réaliser le traitement
suivant:

En quelques mots, je dois trouver un algorithme permettant d'utiliser au
mieux des points de fidélité pour acheter des articles.

Voici l'explication du problème:

Le fichier ARTICLE contient des articles à vendre. Chaque article a un


prix
en EURO, un prix en points de fidélité et un nombre de points de fidélité
octroyé à chaque unité vendue de cet article.

Lors de chaque vente, l'acheteur peut payer soit en EURO, soit en points
fidélité qu'il aura collectionné au cours de ses achats précédents.

Le problème est le suivant: Il faut optimiser le paiement en points de
fidélité. En d'autres mots, le logiciel doit spécifier dans la liste des
articles achetés par le client, lesquels il doit payer au moyen de ses
points de fidélité afin de les utiliser au mieux.

L'acheteur remet au vendeur tous ses points de fidélité. Le vendeur encode
dans le programme le nombre de points reçus.

Il faut à ce moment là que le logiciel, sur base des articles sélectionnés
par l'acheteur, optimise au mieux le paiement au moyen des points fidélité
remis, tout en sachant qu'un article ne peut être payé partiellement avec
des points de fidélité.

Exemple:

L'acheteur souhaite acheter les articles suivants:

Qtté Article Prix unitaire EUR Prix unitaire
points fidélité

3 A 2.50? 6pts

1 B 5? 15pts

5 C 0.6? 2pts

Le total de points fidélité nécessaire pour payer cet achat est de 43 (2x6
+1x15 + 5x2).

Imaginons que l'acheteur remette au vendeur 16 points de fidélité.

Question: Comment utiliser au mieux ces points pour payer cet achat?

Dans notre exemple, la meilleure utilisation est:

2xA + 2xC = 2x6 + 2x2 = 16 points, solde de points à utiliser = 0

J'ai déjà consulté les archives du forum et j'ai déjà trouvé la fonction
récursive de Fabrice qui fait cela en partie.

Néanmoins, je pense que ce problème est plus complexe car:

1. Il ne faut pas forcément arriver au nombre de points total à utiliser
mais sans approcher au plus, sans toutefois le dépasser. Ainsi, par


exemple,
si l'acheteur remet 30 points au vendeur dans l'exemple cité, je pense que
l'on n'arrive pas à utiliser tous les points remis (30) mais qu'on arrive


au
mieux à 29 (1x15 + 2x6 + 1x2). Il faut dans ce cas que le logiciel me


sorte
l'utilisation optimale à faire des points tout en indiquant le solde de
points (1 dans ce cas) à rendre à l'acheteur.

2. LA quantité d'articles achetés est limité. On doit donc, à l'inverse du
problème de B. Neve, fixer des limites par article qui sont respectivement
les quantités des divers articles achetés par le client (dans notre


exemple
3A, 1B et 5C).

Après avoir bien analysé la fonction récursive de Fabrice, je n'arrive pas


à
trouver la solution.

Quelqu'un peut-il me donner un coup de pouce? Je cale...

Merci d'avance et Bonnes fêtes.

François







Avatar
Fabrice Burghgraeve
salut.

"François Semoulin" a écrit dans le message de
news:bscc8r$ehm$
(...)

Cet algo fonctionne mais il y a, à mes yeux, deux problèmes:
1. Le nombre d'essais pour trouver la solution peut être élevé car, malgré
certains tests, le principe est de tester TOUTES les possibilités!



Exact.
cela tiens a la classe du probleme que tu pose qui est : "trouver le
meilleur moyen"
Il serait plus rapide de chercher "un bon moyen" que "le meilleur moyen".
Mais tu n'as peut-etre pas le choix.

2. Cet algorithme se limite à trois valeurs de prix par article (ptsart).
Or, dans la réalité, ce nombre n'est pas fixe: il peut être de 1, 2, 3,


...

Il faut donc utiliser un tableau dynamique, (ou autre structure dynamique,
mais un tableau est bien adapté)


Quelqu'un peut-il m'aider à résoudre ce problème?
Je ne vois pas de solution pour le 1er problème.


Je pense qu'il n'y en a pas. Il faudra optimiser au maximum, pour que ce
soit le moins lent possible.

Pour le second, il me
semble qu'il faut passer par la récursivité mais je ne m'en sors pas...



Je vais essayer de regarder dans le detail du probleme pour te mettre sur la
voie.
Mais je pense qu'on va arriver a presque la meme chose que l'autre algo
(celui avec le conditionnement)
Il y a toutefois une difference.
Avec le conditionnement, on voulait trouver un conditionnement. On pouvait
donc sortir des qu'on en trouvait un.
Ici, on veut trouver le meilleur, on doit donc tout parcourir, et a chaque
fois qu'on en trouve un, le comparer avec le dernier trouvé pour voir si il
est meilleur.

sinon dans l'idee, ce sera le meme algo.

(...)
> J'ai déjà consulté les archives du forum et j'ai déjà trouvé la fonction
> récursive de Fabrice qui fait cela en partie.
>
> Néanmoins, je pense que ce problème est plus complexe car:
>
> 1. Il ne faut pas forcément arriver au nombre de points total à utiliser
> mais sans approcher au plus, sans toutefois le dépasser. Ainsi, par
exemple,



grosso modo, ca fait un test a changer dans la condition d'arret : changer
un tant que pas > en tant que <
(...)
>
> 2. LA quantité d'articles achetés est limité. On doit donc, à l'inverse


du
> problème de B. Neve, fixer des limites par article qui sont


respectivement
> les quantités des divers articles achetés par le client (dans notre
exemple
> 3A, 1B et 5C).



Dans le probleme de B Neve, il y avait une limite aussi.
Elle etait determinee par le nombre d'articles a conditionner.
Par exemple, si il y avait 100 articles a conditionner, la limite de boites
de 25 etait 4.
Cette limite etait calculee par une division entiere si je me souviens,
alors que dans ton cas elle est à passer en argument.
(on ne sait pas a priori ce que va acheter le client)
Ca revient a compliquer le probleme de B Neve en supposant que celui qui met
en conditionnement dispose d'un nombre limité de chaque boite.
(en vrai, un nombre infini de boite ca n'existe pas, mais je crois qu'on
avait supposé qu'il y en avait assez)

Est-ce que tu pourrais definir ce qu'est le meilleur moyen d'utiliser les
points ?
deja, il faut en utiliser le plus possible...

Est-ce que :
- il faut que le client paye le moins cher possible ?
ou :
- il faut que le magasin fasse le plus de marge possible.
(ainsi, on peut encore compliquer, et prendre en compte la marge que le
magasin fait sur chaque article)


--
Fabrice Burghgraeve
Computer & Services
suivez ce lien pour me repondre en prive :
http://cerbermail.com/?I3GMPRuXDD
Avatar
francois
Bonjour.

Merci de ta réponse Fabrice.

Je reviens sur les deux problèmes que je rencontre.
Problème 1: parcours des solutions possibles pour trouver la solution
optimale.

Après y avoir réflechi, je pense que:
A. La solution est optimale si tous les points remis par l'acheteur
sont utilisés pour acheter les articles choisis, ce qui revient à dire
qu'à mon avis, il faut tester en premier l'algorithme que tu as mis au
point pour B Neve. Si celui-ci donne le résultat, il est inutile de
chercher plus loin une autre solution puisque dans ce cas, tous les
points sont utilisés.
En reprenant mon exemple, si l'acheteur remet 16 points au vendeur,
celui-ci déduira de sa facture 2 articles A et 2 articles C, pour un
total de 16 points.
Ton algorithme donnera cette solution qui en terme de temps de
réponse, je pense, sera optimale.
B. S'il est impossible d'utiliser tous les points remis (cas pour
lequel ton alogo renvoie "ah ben non alors"), il faut dans ce cas
commencer à passer toutes les possibilités en revue afin de trouver la
meilleure solution possible. Pour cela aussi, j'ai trouvé un moyen
d'optimiser. Tu verras que dans chaque boucle POUR de ma procédure
j'ai testé le nombre de points calculés. En effet, comme chaque boucle
POUR incrémente de façon CROISSANTE les indices, il est facile
d'arrêter la boucle dès que le nombre de points calculés par l'algo
est supérieur au nombre de points remis par l'acheteur.
Cela limite donc les solutions parcourues mais néanmoins, le nombre
peut encore être élevé.
Voilà où j'en suis actuellement. Vois-tu d'autres façons d'optimiser?

Par contre pour le 2ème problème de nombre d'articles ayant des prix
en points différents, je n'ai pas trouvé de solution... j'ai en fait
du mal à conceptualiser la récusrivité dans la gestion des boucles
pour imbriqueés...
Et tant que ce problème n'est pas résolu, je n'ai pas la solution au
problème.

En résumé, les données dont on dispose sont les suivantes:
1. Nombre de points de fidélité remis par l'acheteur: PTSFIDREMIS
2. Tableau dynamique avec, POUR CHAQUE ARTICLE AYANT UN PRIX EN POINTS
DIFFERENT, les deux infos suivantes:
La quantité achetée (QUANTITE) et le prix en points de fidélité
(PRIXPOINTS)

L'algo doit retourner les infos suivantes:
1. Pour chaque article du tableau dynamique, la quantité calculée par
l'algo payable avec les points de fidélité.
2. Le solde éventuel de points non utilisés.

Quant à la solution optimale du problème, c'est bien entendu
d'utiliser le maximum de points remis par l'acheteur afin d'acheter
les articles choisis.
Le programme doit donc, sur base des quantités et articles choisis par
l'acheteur ainsi que du nombre de points remis par celui-ci au
vendeur, trouver la combinaison optimale des articles achetés pour
utiliser si possible tous les points remis.
Une fois cette solution trouvée, il est en suite facile de calculer ce
que l'acheteur doit encore payer en EUR cette fois pour acheter
éventuellement le reste des articles une fois les points de fidélité
utilisés.

On peut, comme tu le mentionnes, affiner le problème en affectant à
chaque article un coéfficient de profit pour le magasin afin que
l'algo en tienne compte dans le choix des articles...
Si tu vois comment l'intégrer dans l'algo, ce paramètre est le
bienvenu...

Encore merci de ton aide.

François



"Fabrice Burghgraeve" wrote in message news:<bsh7hj$oq3$...
salut.

"François Semoulin" a écrit dans le message de
news:bscc8r$ehm$
(...)
>
> Cet algo fonctionne mais il y a, à mes yeux, deux problèmes:
> 1. Le nombre d'essais pour trouver la solution peut être élevé car, malgré
> certains tests, le principe est de tester TOUTES les possibilités!

Exact.
cela tiens a la classe du probleme que tu pose qui est : "trouver le
meilleur moyen"
Il serait plus rapide de chercher "un bon moyen" que "le meilleur moyen".
Mais tu n'as peut-etre pas le choix.

> 2. Cet algorithme se limite à trois valeurs de prix par article (ptsart).
> Or, dans la réalité, ce nombre n'est pas fixe: il peut être de 1, 2, 3,
...

Il faut donc utiliser un tableau dynamique, (ou autre structure dynamique,
mais un tableau est bien adapté)

>
> Quelqu'un peut-il m'aider à résoudre ce problème?
> Je ne vois pas de solution pour le 1er problème.
Je pense qu'il n'y en a pas. Il faudra optimiser au maximum, pour que ce
soit le moins lent possible.

>Pour le second, il me
> semble qu'il faut passer par la récursivité mais je ne m'en sors pas...

Je vais essayer de regarder dans le detail du probleme pour te mettre sur la
voie.
Mais je pense qu'on va arriver a presque la meme chose que l'autre algo
(celui avec le conditionnement)
Il y a toutefois une difference.
Avec le conditionnement, on voulait trouver un conditionnement. On pouvait
donc sortir des qu'on en trouvait un.
Ici, on veut trouver le meilleur, on doit donc tout parcourir, et a chaque
fois qu'on en trouve un, le comparer avec le dernier trouvé pour voir si il
est meilleur.

sinon dans l'idee, ce sera le meme algo.

(...)
> > J'ai déjà consulté les archives du forum et j'ai déjà trouvé la fonction
> > récursive de Fabrice qui fait cela en partie.
> >
> > Néanmoins, je pense que ce problème est plus complexe car:
> >
> > 1. Il ne faut pas forcément arriver au nombre de points total à utiliser
> > mais sans approcher au plus, sans toutefois le dépasser. Ainsi, par
> exemple,

grosso modo, ca fait un test a changer dans la condition d'arret : changer
un tant que pas > en tant que < >
(...)
> >
> > 2. LA quantité d'articles achetés est limité. On doit donc, à l'inverse
du
> > problème de B. Neve, fixer des limites par article qui sont
respectivement
> > les quantités des divers articles achetés par le client (dans notre
exemple
> > 3A, 1B et 5C).

Dans le probleme de B Neve, il y avait une limite aussi.
Elle etait determinee par le nombre d'articles a conditionner.
Par exemple, si il y avait 100 articles a conditionner, la limite de boites
de 25 etait 4.
Cette limite etait calculee par une division entiere si je me souviens,
alors que dans ton cas elle est à passer en argument.
(on ne sait pas a priori ce que va acheter le client)
Ca revient a compliquer le probleme de B Neve en supposant que celui qui met
en conditionnement dispose d'un nombre limité de chaque boite.
(en vrai, un nombre infini de boite ca n'existe pas, mais je crois qu'on
avait supposé qu'il y en avait assez)

Est-ce que tu pourrais definir ce qu'est le meilleur moyen d'utiliser les
points ?
deja, il faut en utiliser le plus possible...

Est-ce que :
- il faut que le client paye le moins cher possible ?
ou :
- il faut que le magasin fasse le plus de marge possible.
(ainsi, on peut encore compliquer, et prendre en compte la marge que le
magasin fait sur chaque article)


Avatar
Sylvestre
Hello

Il semblerait que ton problème est un classique problème d'optimisation,
peut
être devrait regarder du coté des solution au problème du voyageur de
commerce, je
pense notament au "recuit simulé".



"François Semoulin" a écrit dans le message news:
bsbt5e$smu$
Bonjour.

Je suis à la recherche d'un algorithme WD pour réaliser le traitement
suivant:

En quelques mots, je dois trouver un algorithme permettant d'utiliser au
mieux des points de fidélité pour acheter des articles.

Voici l'explication du problème:

Le fichier ARTICLE contient des articles à vendre. Chaque article a un


prix
en EURO, un prix en points de fidélité et un nombre de points de fidélité
octroyé à chaque unité vendue de cet article.

Lors de chaque vente, l'acheteur peut payer soit en EURO, soit en points
fidélité qu'il aura collectionné au cours de ses achats précédents.

Le problème est le suivant: Il faut optimiser le paiement en points de
fidélité. En d'autres mots, le logiciel doit spécifier dans la liste des
articles achetés par le client, lesquels il doit payer au moyen de ses
points de fidélité afin de les utiliser au mieux.

L'acheteur remet au vendeur tous ses points de fidélité. Le vendeur encode
dans le programme le nombre de points reçus.

Il faut à ce moment là que le logiciel, sur base des articles sélectionnés
par l'acheteur, optimise au mieux le paiement au moyen des points fidélité
remis, tout en sachant qu'un article ne peut être payé partiellement avec
des points de fidélité.

Exemple:

L'acheteur souhaite acheter les articles suivants:

Qtté Article Prix unitaire EUR Prix unitaire
points fidélité

3 A 2.50? 6pts

1 B 5? 15pts

5 C 0.6? 2pts

Le total de points fidélité nécessaire pour payer cet achat est de 43 (2x6
+1x15 + 5x2).

Imaginons que l'acheteur remette au vendeur 16 points de fidélité.

Question: Comment utiliser au mieux ces points pour payer cet achat?

Dans notre exemple, la meilleure utilisation est:

2xA + 2xC = 2x6 + 2x2 = 16 points, solde de points à utiliser = 0

J'ai déjà consulté les archives du forum et j'ai déjà trouvé la fonction
récursive de Fabrice qui fait cela en partie.

Néanmoins, je pense que ce problème est plus complexe car:

1. Il ne faut pas forcément arriver au nombre de points total à utiliser
mais sans approcher au plus, sans toutefois le dépasser. Ainsi, par


exemple,
si l'acheteur remet 30 points au vendeur dans l'exemple cité, je pense que
l'on n'arrive pas à utiliser tous les points remis (30) mais qu'on arrive


au
mieux à 29 (1x15 + 2x6 + 1x2). Il faut dans ce cas que le logiciel me


sorte
l'utilisation optimale à faire des points tout en indiquant le solde de
points (1 dans ce cas) à rendre à l'acheteur.

2. LA quantité d'articles achetés est limité. On doit donc, à l'inverse du
problème de B. Neve, fixer des limites par article qui sont respectivement
les quantités des divers articles achetés par le client (dans notre


exemple
3A, 1B et 5C).

Après avoir bien analysé la fonction récursive de Fabrice, je n'arrive pas


à
trouver la solution.

Quelqu'un peut-il me donner un coup de pouce? Je cale...

Merci d'avance et Bonnes fêtes.

François







Avatar
Fabrice Burghgraeve
salut.

"Fran?ois" a écrit dans le message de
news:
Bonjour.

Merci de ta réponse Fabrice.

Je reviens sur les deux problèmes que je rencontre.
Problème 1: parcours des solutions possibles pour trouver la solution
optimale.

Après y avoir réflechi, je pense que:
A. La solution est optimale si tous les points remis par l'acheteur
sont utilisés pour acheter les articles choisis, ce qui revient à dire
qu'à mon avis, il faut tester en premier l'algorithme que tu as mis au
point pour B Neve. Si celui-ci donne le résultat, il est inutile de
chercher plus loin une autre solution puisque dans ce cas, tous les
points sont utilisés.


(...)
B. S'il est impossible d'utiliser tous les points remis (cas pour
lequel ton alogo renvoie "ah ben non alors"), il faut dans ce cas
commencer à passer toutes les possibilités en revue afin de trouver la
meilleure solution possible.



En fait, l'algorithme que j'ai mis au point parcours toutes les solutions.
Seulement, il arrete que il en trouve une puisqu'alors rien ne sert d'aller
plus loin.
Il ne faut donc pas l'utiliser "avant", mais le modifier de facon a ce que :
- soit il trouve une solution optimale (tous les points utilises) et il
s'arrete
- soit il ne trouve pas "le compte juste", auquel cas il faut qu'il sache
donner le meilleur resultat

Pour cela aussi, j'ai trouvé un moyen
d'optimiser. Tu verras que dans chaque boucle POUR de ma procédure
j'ai testé le nombre de points calculés.
En effet, comme chaque boucle
POUR incrémente de façon CROISSANTE les indices, il est facile
d'arrêter la boucle dès que le nombre de points calculés par l'algo
est supérieur au nombre de points remis par l'acheteur.



C'est une erreur de faire la boucle de facon croissante. Il faut la faire de
facon decroissante.
car tu as plus de chance que ta solution optimale utilise beaucoup
d'articles plutot que peu :)

tu vas parcourir toutes les combinaisons possibles d'articles.
pour determiner le depart de la boucle decroissante, (pour un article donc)
tu dis que :
- soit il y a plus de points et le nombre maximal d'articles est alors le
debut de la boucle
- soit il y en a moins et c'est (nbpoints/valeur_article) (en entier. il
reste alors des articles qui n'utiliseront pas de points, et des points
qu'il faudra utiliser pour d'autres articles)

En plus, dans ce que j'avais fait, je parcourais le tableau (des
conditionnements je crois) en partant du plus haut indice.
Ca avait le seul interet de ne pas avoir a recopier le tableau entre chaque
appel recursif.

Cela limite donc les solutions parcourues mais néanmoins, le nombre
peut encore être élevé.


les gens achetent tant d'articles que ca d'un coup ???
Voilà où j'en suis actuellement. Vois-tu d'autres façons d'optimiser?



ne pas considerer qu'il y a 3 articles A a 10 points et 2 articles B a 10
points. Considerer plutot qu'il y a 5 articles a 10 points.
Quand on traite le dernier article, ne pas faire de boucle, mais utiliser
directement le maximum de points.


Par contre pour le 2ème problème de nombre d'articles ayant des prix
en points différents, je n'ai pas trouvé de solution... j'ai en fait
du mal à conceptualiser la récusrivité dans la gestion des boucles
pour imbriqueés...



Alors je vais t'aider :)
il ne faut pas penser à modifier les boucles imbriquees, mais penser
directement "en recursif"

Alors voila le probleme.
le client vient payer N articles.
il a P points de fidelite.
parmi ses N articles,
il y a N1 articles a P1 points
N2 articles a P2 points
etc
On veut qu'il utilise le plus possible de points de fidelite.
Combien faut t'il utiliser d'articles à P1, P2 etc points ?

Comment aborder ce probleme ?
2 parties :

1)On veut essayer toutes les combinaisons,
2)pour trouver la meilleure.

Pour parcourir toutes les combinaisons, comment faire ?
on dit ceci :
trouver toutes les combinaisons de P1,P2,P3,... ca revient a essayer chaque
solution possible de P1,
et pour chacune de ces solutions, essayer toutes les combinaisons de
P2,P3,...
Essayer toutes les combinaisons de P2,P3, ... ca revient a essayer chaque
solution possible de P2,
et pour chacune de ces solutions essayer toutes le combinaisons de P3,...

Voila donc le concept de la recursivite qui apparait.
Est-ce que ca va expliqué comme ça ?

Après, tu traduis "betement" ce francais en langage informatique et ca te
donne un algo du style :
procedure parcourir_solutions (tb_articles, nb_articles_tb, local
points_restants)
// renvoi les points utilises
pour i = tb_articles[nb_articles_tb].nb_articles à 0 pas -1
points_restant_tempo = points_restant -
tb_articles[nb_articles_tb].valeur_points
parcourir_solutions(tb_articles,nb_articles_tb -1,
points_restant_tempo)
fin
fin

Hop voila la procedure recursive.
Elle est "toute nue" sans optimisation aucune, et elle ne trouve pas la
meilleure solution
C'est juste la traduction de ce que je disais plus haut en francais pour
expliquer comment pondre une procedure recursive a partir d'un enonce.
Apres, on va voir pour modifier ce pseudo-code pour l'optimiser, puis faire
en sorte qu'il trouve la meilleure solution.

Mais pour l'instant je fais une pause clope et je vais bosser un peu quand
meme avant la suite ... :)

(ah oui au fait... Le recuit j'en avait entendu parler mais je me souviens
plus)

(...)


--
Fabrice Burghgraeve
Computer & Services
suivez ce lien pour me repondre en prive :
http://cerbermail.com/?I3GMPRuXDD
Avatar
Manu
>
(ah oui au fait... Le recuit j'en avait entendu parler mais je me souviens
plus)



Pour info, c'est un pb d'optimisation capable d'être résolu à l'aide du
simplexe. Du moment que tu as une fonction à minimiser (ou maximiser), des
contraites suffisantes à vérifier...

Ensuite pour trouver des solutions les meilleures tu as les méthodes
heuristiques et méta heuristiques, très utiles pour les pbs NP complets. On
à par exmeple : le recuit simulé, les algo génétiques, l'algo tabou, ...

Emmanuel
Avatar
Fabrice Burghgraeve
salut.

"Manu" a écrit dans le message de
news:bsrikb$ot5$
>
> (ah oui au fait... Le recuit j'en avait entendu parler mais je me


souviens
> plus)

Pour info, c'est un pb d'optimisation capable d'être résolu à l'aide du
simplexe. Du moment que tu as une fonction à minimiser (ou maximiser), des
contraites suffisantes à vérifier...

Ensuite pour trouver des solutions les meilleures tu as les méthodes
heuristiques et méta heuristiques, très utiles pour les pbs NP complets.


On
à par exmeple : le recuit simulé, les algo génétiques, l'algo tabou, ...



les algos genetiques je connais.
une heuristique aussi il y en a une simple dans ce cas la : mettre tous les
points possibles pour l'article le plus "cher en points", puis avec le reste
des points mettre tout ce qu'on peut dans le deuxieme plus cher etc.

Le probleme est que ces algos donnent "un bon moyen", mais pas "le meilleur
moyen"

Ils sont utilises dans des cas d'ecole ou on a vraiment des centaines de
donnees et ou la methode "bourrin" est inaplicable car elle conduit a des
dizaines d'annees de calcul.
Dans la vrai vie, comme dans cet exemple, le client ne va pas acheter des
centaines d'articles avec des valeurs de points differentes, et il n'aura
pas non plus accumule des millions de poins de fidelite.
Bien souvent egalement, on se contente d'une "bonne" solution, meme si elle
n'est pas "la meilleure" (heuristique)
En plus, un algo genetique avec si peu de donnees, ca va etre trop couteux a
mettre en place (en temps d'execution). Ca fait un peu marteau pour ecraser
une mouche. Et ca ne va pas donner non plus forcement le meilleur moyen,
mais juste un bon moyen.
Dans la vrai vie, les algos genetiques sont utilises de preference a des
methodes statistiques, par exemple par les boite de VPC pour faire de la pub
ciblée. (il ont des bases de milliers de clients, avec des millions de
commandes deja passées)
Ou par les matheux pour faire des calculs d'optimums sur des fonctions
"tordues"

Le recuit simule et l'algo tabou, j'en avait entendu parler, mais je ne m'en
souviens plus du tout.

Je pense que dans le cas present, il faut partir sur un algo "bourrin" et
l'optimiser. (il y a des contraintes)


Emmanuel




--
Fabrice Burghgraeve
Computer & Services
suivez ce lien pour me repondre en prive :
http://cerbermail.com/?I3GMPRuXDD

(P.S. : windev. si j'lai dit :) )
Avatar
Fabrice Burghgraeve
re.

(...)

Alors voila le probleme.
le client vient payer N articles.
il a P points de fidelite.
parmi ses N articles,
il y a N1 articles a P1 points
N2 articles a P2 points
etc
On veut qu'il utilise le plus possible de points de fidelite.
Combien faut t'il utiliser d'articles à P1, P2 etc points ?

Comment aborder ce probleme ?
2 parties :

1)On veut essayer toutes les combinaisons,
2)pour trouver la meilleure.



(...)
procedure parcourir_solutions (tb_articles, nb_articles_tb, local
points_restants)
// renvoi les points utilises



ah le commentaire etait une erreur :)
en fait tout ce qui concernait les points est faux j'avais une longueur
d'avance,mais maintenant je m'en rend compte.
Pour tout parcourir, on s'en fiche du nombre de points restants. Bref. Il
manquanit un *i pour determiner points_restant_tempo

pour i = tb_articles[nb_articles_tb].nb_articles à 0 pas -1
points_restant_tempo = points_restant -
tb_articles[nb_articles_tb].valeur_points
parcourir_solutions(tb_articles,nb_articles_tb -1,
points_restant_tempo)
fin
fin



(...)

je m'apercoit aussi qu'il manquait la condition d'arret de la recursivite
bien sur, qui est qu'on s'arrete quand on a testé tous les articles.
On la met en debut de la proceudre :
si nb_article_tb = 0 alors retour.

ok donc maintenant on va modifier ca pour :
1) trouver la meilleure solution
2) optimiser parce que c'est trop long.

pour trouver la meilleure solution, on dit la chose suivante :
on va trouver une solution de la forme : n1*P1 + n2*P2 + n3*P3
avec n1 le nombre d'articles à P1 points parmi les N1 du client
trouver la meilleure solution consiste a parcourir chaque choix possible de
n1
Pour chacun de ces choix, il faut prendre la meilleure solution de
(n2,n3,...)
et regarder si ce qu'on obtient est meilleur qu'avant. (sauf a la premiere
iteration evidement)
trouver la meilleure solution de (n2,n3...) consiste a parcourir toutes les
valeurs de n2,
et pour chacune d'elle (sauf la premiere) trouver la meilleure combinaison
de (n3,...)
et regarder si onobtient mieux qu'avant.
etc etc et la recursivite apparait encore une fois.
(et tu vois que c'est presque la meme facon d'enoncer que precedement.)

ce qui donne traduit en pseudo-langage informatique :
procedure trouve_meilleure (tb_article, nb_articles_tb, local
points_restants, tb_meilleur)
// tb_meilleur va contenir n1,n2,n3 etc. il doit etre remmpli de 0 au depart

si nb_article_tb = 0 alors retour

tb_meilleur_tempo est un tableau de nb_articles_tb-1 entiers
meilleur_tb_meilleur est un tableu de nb_articles_tb entiers

pour i = tb_articles[nb_articles_tb].nb_articles à 0 pas -1
trouve_meilleur(tb_articles,nb_articles_tb -1,
points_restant_tempo,tb_meilleur_tempo)
si tb_articles[nb_articles_tb].valeur_points * i + somme_des_points
(tb_meilleur_tempo,tb_articles) > somme_des_points(meilleur_tb_meilleur,
tb_articles) // on regarde si la solution trouvée est meilleure que la
précédente
alors
meilleur_tb_meilleur[1 à nb_articles_tb -1] tb_meilleur_tempo
meilleur_tb_meilleur[nb_articles_tb] = i
fin
fin
// fin de la boucle. qui essaye tous les nb_article_tb-iemes articles
meileur_tb_meilleur contient lemeilleur
tb_meilleur = tb_meilleur_tempo
fin


voila cet algo doit marcher mais il n'est pas optimisé et va vraiment tout
parcourir.
attention : c'est du pseudo-code (notament les affectation de tableaux)

François, est-ce que tu peux implementer ca proprement (j'ai pas testé) et
dire si ca marche.
(chacun son tour de bosser non mais ;-) )
Apres alors on verra pour l'optimisation.

A+


--
Fabrice Burghgraeve
Computer & Services
suivez ce lien pour me repondre en prive :
http://cerbermail.com/?I3GMPRuXDD
Avatar
Fabrice Burghgraeve
re.
Gulp je veux aller trop vite et je fais que des conneries...
Apres je me relis, je reflechis a ce que j'ai ecrit, et je me dis que
j'aurais du relire et reflechir *avant* de poster.
:)

(...)
procedure trouve_meilleure (tb_article, nb_articles_tb, local
points_restants, tb_meilleur)
// tb_meilleur va contenir n1,n2,n3 etc. il doit etre remmpli de 0 au


depart

si nb_article_tb = 0 alors retour

tb_meilleur_tempo est un tableau de nb_articles_tb-1 entiers
meilleur_tb_meilleur est un tableu de nb_articles_tb entiers

pour i = tb_articles[nb_articles_tb].nb_articles à 0 pas -1



remettre ici le calcul de points_restants tempo :
points_restant_tempo = points_restant -
tb_articles[nb_articles_tb].valeur_points*i


trouve_meilleur(tb_articles,nb_articles_tb -1,
points_restant_tempo,tb_meilleur_tempo)


(...)



si nb_article_tb = 0 alors retour
tb_meilleur_tempo est un tableau de nb_articles_tb-1 entiers


ca ca va planter. en effet, pour le dernier article, nb_article_tb vaudra 1.
du coup, ca devient : tb_meilleur_tempo est un tableau de 0 entiers.

Il faut changer ces 2 lignes en :
si nb_article_tb = 1 alors
tb_meilleur[1]=points_restant / tb_article[1].nombre_point
si tb_meilleur[1] > tb_article[1].nb_article alors tb_meilleur[1] tb_article[1].nb_article // cas ou il resterait des points a la fin
retour
fin


--
Fabrice Burghgraeve
Computer & Services
suivez ce lien pour me repondre en prive :
http://cerbermail.com/?I3GMPRuXDD