cs_eric89
Messages postés10Date d'inscriptionjeudi 28 août 2003StatutMembreDernière intervention 5 juin 2007
-
10 mai 2007 à 09:09
cs_eric89
Messages postés10Date d'inscriptionjeudi 28 août 2003StatutMembreDernière intervention 5 juin 2007
-
5 juin 2007 à 15:24
Bonjour
Je cherche un algorithme pour chercher le plan chargement de camions.Voici mon problème:
J'ai un camion avec 6 cuves qui ont comme capacités :
1ere cuve 2500 kg maxi
2eme cuve 1500 kg maxi
3eme cuve 1500 kg maxi
4eme cuve 2500 kg maxi
5eme cuve 2000 kg maxi
6eme cuve 2000 kg maxi
J'ai une commande par exemple
1ere ligne Client1 Produit 1 2200 Kg
2eme ligne Client2 Produit 2 3000 Kg
3eme ligne Client3 Produit 3 4500 Kg
4eme ligne Client4 Produit 4 1000 Kg
Les bases de ce problèmes sont les suivantes on ne peut pas mélanger les produits et on ne peut pas mélanger les commandes.
L'algorithme devra me trouver la solution suivante:
le Produit 1 ira dans la cuve 1
le Produit 2 ira dans les cuves 2 et 3
le Produit 3 ira dans les cuves 4 et 5
le Produit 4 ira dans la cuve 6
Merci à celui ou celle qui poura me répondre
Eric H
poy20
Messages postés40Date d'inscriptionmardi 9 novembre 2004StatutMembreDernière intervention19 janvier 2009 10 mai 2007 à 09:40
Salut,
Je suppose que le but est d'utiliser la plus petite cuve possible à chaque ligne de commande ...?
Par contre y-a-t-il un paramètre "date" ? Histoire de savoir si une cuve est déjà prise par une autre commande le même jour, et qui serait donc indisponible.
Sinon voici une première idée qui permettra d'ouvrir le débat :
Dim Cuve1 as integer =2500
Dim Cuve2 as integer = 1500
Dim Cuve3 as integer = 1500
Dim Cuve4 as integer = 2500
Dim Cuve5 as integer = 2000
Dim Cuve6 as integer = 2000
Dim CuveUtilise as String = ""
'KilosProduit correspond à la charge de la première commande
Private Function RechercheCuve (KilosProduit as integer) as String
If KilosProduit <= 1500 then
CuveUtilise &= "Cuve 2 "
ElseIf KilosProduit <= 2000 then
CuveUtilise &= "Cuve 5 "
Elseif KilosProduit <= 2500 then
CuveUtilise &= "Cuve 4 "
ElseIf KilosProduit > 2500 then 'compare à la plus grande cuve
CuveUtilise &= "Cuve 4 "
RechercheCuve(kilosProduit - 2500)
End If
Return(CuveUtilse)
End Function
Bon je sais bien, s'il boucle 2 fois il peut utiliser plusieurs fois la même cuve, mais avant d'approfondir la chose avec des booléens pour vérifier la dispo des cuves, je laisse Eric répondre pour savoir si c'est bien ce qu'il cherche....
cs_eric89
Messages postés10Date d'inscriptionjeudi 28 août 2003StatutMembreDernière intervention 5 juin 2007 10 mai 2007 à 10:05
Cela ressemble à ce que je veux mais effectivement on peut utiliser une cuve plusieurs fois.Il faudra aussi pouvoir retrouver où auront été mises les commandes.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 10 mai 2007 à 21:48
Euh...
Toujours de passage... et de bien loin...
Voyons donc : ton problème de cuves ressemble tout simplement à celui d'un monnayeur (une caisse, des billets et pièces.
... une somme à faire verser par la caisse le plus "adroitement" possible... je ne vois aucune différence de raisonnement....)!
Remplace donc tes cuves par des valeurs faciales...
un véritable jeu d'enfant, ma foi ... (juste un peu de réflexion et l'utilisation astucieuse de l'opérateur Mod (aide en ligne)...
Tu veux bien t'y mettre, s'il te plait ?
On verra après (si tu as bien voulu d'abord y mettre un peu du tien ...)
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 14 mai 2007 à 09:30
On va régler celà cet après midi (ce sera assez facile, ne t'inquiète pas)...
Mais déjà, je viens de voir un petit truc qui m'embête :
Modifie ceci (remplace l'ancienne ligne par celle en rouge ici) :
Private Sub Command1_Click()
If quantite.Text = "" Then quantite.SetFocus: Exit Sub
If matiere.Text = "" Then matiere.SetFocus: Exit Sub
listcommande.AddItem Format(quantite.Text, "000000") & " litres de " & matiere.Text
quantite.Text = ""
matiere.Text = ""
End Sub
Voilà pour l'instant .
Le reste cet après-midi car je dois m'absenter.
tu verras...
J'ai fait une petite erreur dans l'algo de recherche des cuves dispo, en voici la correction.
Par contre il faut désormais classer les cuve dans ton form1 dans l'oredre inverse ...
Dim cuve6 AsNew Cuve("Cuve 3", 1500)
Dim cuve5 AsNew Cuve("Cuve 2", 1500)
Dim cuve4 AsNew Cuve("Cuve 6", 2000)
Dim cuve3 AsNew Cuve("Cuve 5", 2000)
Dim cuve2 AsNew Cuve("Cuve 4", 2500)
Dim cuve1 AsNew Cuve("Cuve 1", 2500)
J'ai un petit test, ça à l'air de fonctionner correctement, ar contre ça ne gère pas la possibilité qu'il n'y ait
plus de cuve dispo... Mais ça doit pas être sorcier.
N'hésite pas !
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 11 mai 2007 à 08:44
Tu me fais travailler de bon matin (et avant ce soir !) sans VB sous la main....
Voilà un monnayeur (gaffe : je n'ai pas VB sous la main et je peux avoir fait une erreur en codant à "main levée")
une Form avec un bouton de commande command1 et une listbox List1
Regarde bien (surtout les arrays notes et dispo (ce sont tes citernes)... et le montant (c'est ce que tu as à mettre dans tes citernes...)
Tu as là le principe d'une répartition la mieux organisée pour utiliser au mieux tes billets/pièces (tes citernes, donc)...
Il te suffit de comprendre ce mécanisme et d'adapter à ton cas...
Private notes, dispo, dispo1
Private Sub Command1_Click()
Dim rep As Double, arep As Double, montant As Double, i As Integer, combien As Double
arep = 3127.98
montant = CDbl(arep) 'ici le montant à sortir (analogie : la commande d'u client)
List1.Clear
For i = 0 To UBound(notes)
combien = Int(CDbl(montant) / CDbl(notes(i)))
If combien > dispo(i) Then combien = dispo(i)
dispo(i) = dispo(i) - combien
montant = montant - (combien * CDbl(notes(i)))
rep = rep + (combien * CDbl(notes(i)))
If combien > 0 Then List1.AddItem combien & " * " & notes(i)
Next
If arep > rep Then
Dim avoir As Double
For i = 0 To UBound(notes)
avoir = avoir + (dispo(i) * notes(i))
Next
If avoir > (arep - rep) Then
MsgBox " pas de quoi faire appoint "
Else
MsgBox " pas assez et bous devez encore " & arep - rep
End If
List1.Clear
Let dispo = dispo1
Else
Let dispo1 = dispo
End If
End Sub
Private Sub Form_Activate()
'ici les valeurs faciales de tes billets et pièces (analogie : la contenance de tes citernes)
notes = Array(500, 200, 100, 50, 20, 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01)
'ici ce qu'il te reste à chaque sortie comme billets et pièces (analogie : ce qu'il te reste dans chaque citerne)
' au départ (stock encore non entamé) on dit ce dont on dispose (la capacité de tes citernes vides, donc)
dispo = Array(3, 50, 20, 30, 100, 150, 300, 280, 100, 200, 190, 160, 200, 110, 10)
End Sub
Attention : comme je ne peux vérifier ma syntaxe (sans VB sous la main), elle comportre peut-être une erreur ou deux à corriger ici ou là ... mais ce doit alors être insignifiant et facile à corriger...
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 11 mai 2007 à 12:00
Oui ?
Et quelle est donc la petite modif à apporter ? (tu ne la vois pas ?)
Il te suffit de dire que ta cuve est indisponible dès que tu l'as utilisée, même en partie...
Tu as pour cela la Array dispo, non ? (si cuve utilisée, même en partie, le dispo correspondant estr mis à zéro ...)
Ton problème est autre, en réalité : contrairement au monnayeur pur (qui ne distribue un billet que si la valeur restant à distribuer est supérieure ou égale à la valeur faciale de ce billet), il te faut faire un peu le contraire (rechercher la cuve de capacité égale ou, à défaut, immédiatement supérieure... c'est tout !!).
Tu as donc un exemple de répartition (monnayeur) et il te convient de l'adapter un tout petit peu...et cette adaptation réclamera moins de code (que tu as déjà) que de l'utilisation de ton intelligence ! Fais donc un petit algorithme d'abord (tu me parais avoir surtout besoin de réfléchir et d'organiser ta p)ensée...) Une autre fois : en ce qui concerne le code de répart(ition... tu l'as déjà !!!
En d'autres termes : ne pas confondre le raisonnement avant de coder et le code à proprement parler .. Tu me parais ne pas avoir encore terminé ton étape de raisonnement avant même de coder.
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 11 mai 2007 à 22:07
Bon...
Me voilà enfin devant une machine "équipée" comme il le faut...
Et d'excellente humeur, je dois dire...
Je vais donc m'occuper de toi et on va faire autrement...
Tu vas commencer par ceci :
un petit projet et sur ta Form :
1) à gauche, un au dessous de l'autre et dans cet ordre là :
- une textbox nommée matiere
- une textbox nommée quantité
-un bouton de commande nommé Command1
- une listbox nommée listcommande et avec sa propriété Sorted à True
2) à la droite de cette "colonne" et toujours de haut en bas:
- une textbox nommée citerne
- un bouton de commande nommé Compmand2
- une listbox nommée listeciternes, avec sa propriété Sorted = True
3) à la droite de ces deux colonnes :
une textbox nommée Resultat et avec sa propriété Multiline = True
4) quelque part en dessous de ces trois colonnes : un bouton de commande nommé Command3
Tu as tout deviné, nous sommes partis pour faire un petit truc polyvalent, qui te permettra de défrinir tes commandes et tes citernes....
Quand tu seras prêt, fais-le moi savoir... le reste sera un jeu d'enfant et nous nous amuserons ensemble, si tu le souhaites....
(tu as de la chance : je suis vraiment de bonne humeur )
jmfmarques
Messages postés7666Date d'inscriptionsamedi 5 novembre 2005StatutMembreDernière intervention22 août 201427 14 mai 2007 à 08:38
Bon.
... (je ne t'attendais plus)
Voilà donc ce que je viens de faire rapidement
Tu dois :
- d'abord enregistrer toutes tes commandes (matiere et quantité puis click sur command1 pour chaque commande)
- enregistrer toutes tes citernes (contenance puis click sur command2 pour chaque citerne)
puis : clique sur command3 pour obtenir la répartition de tes commandes
Essaye déjà celà, que je perfectionnerai ensuite (j'ai fait à toute allure et n'ai que peu testé jusqu'à présent)
Dis-moi si ce chemin te parait bon, dékà...
Je continuerai cet après-midi en fonction de ta réponse
Private Sub Command1_Click()
If quantite.Text = "" Then quantite.SetFocus: Exit Sub
If matiere.Text = "" Then matiere.SetFocus: Exit Sub
listcommande.AddItem quantite.Text & " litres de " & matiere.Text
quantite.Text = ""
matiere.Text = ""
End Sub
Private Sub Command2_Click()
If citerne.Text = "" Then Exit Sub
listeciternes.AddItem citerne.Text
citerne.Text = ""
End Sub
Private Sub Command3_Click()
resultat.Text = ""
total_commandes = faire_total(listcommande)
total_citernes = faire_total(listeciternes)
If total_commandes > total_citernes Then
MsgBox "pas bon ( " & total_commandes & " > " & total_citernes & ")": Exit Sub
End If
While listcommande.ListCount > 0
traitercommande listcommande.ListCount - 1
'MsgBox listcommande.ListCount - 1
Wend
End Sub
Private Sub Form_Activate()
listcommande.Clear
listeciternes.Clear
quantite.Text = ""
matiere.Text = ""
citerne.Text = ""
End Sub
Private Function faire_total(ctrl As ListBox)
For i = 0 To ctrl.ListCount - 1
faire_total = faire_total + Val(ctrl.List(i))
Next
End Function
Private Sub traitercommande(j)
resultat.Text = resultat.Text & "traitement de la commande de " & listcommande.List(j)
acaser = Val(listcommande.List(j))
While acaser > 0
For i = listeciternes.ListCount - 1 To 0 Step -1
If acaser <= Val(listeciternes.List(i)) Then
quelle_citerne = i
resultat.Text = resultat.Text & vbCrLf & acaser & " litres dans citerne de " & listeciternes.List(i) & " litres"
listeciternes.RemoveItem (i)
acaser = 0
Exit For
End If
Next
If acaser > 0 Then resultat.Text = resultat.Text & vbCrLf & Val(listeciternes.List(quelle_citerne)) & " litres dans citerne de " & listeciternes.List(quelle_citerne) & " litres"
acaser = acaser - Val(listeciternes.List(quelle_citerne))
If acaser > 0 Then listeciternes.RemoveItem (quelle_citerne)
DoEvents
Wend
listcommande.RemoveItem (j)
End Sub