2010-10-28 1 views
2

L'affectation est la suivante:Simulation de station-service: comment simuler des voitures à intervalles aléatoires?

La station d'essence se compose de 2 pompes. Chaque pompe a une certaine quantité de carburant qu'elle peut distribuer. Les voitures arrivent à des intervalles aléatoires et tentent d'utiliser l'une des deux pompes:

- Si une pompe est disponible et a du carburant, la voiture est immédiatement autorisée à l'utiliser. Chaque voiture nécessite une certaine quantité de carburant (nombre aléatoire), et doit attendre un temps proportionnel à cette quantité de carburant. Par exemple, une voiture peut nécessiter 6 gallons et utilisera la pompe pendant 3sec, une autre voiture peut nécessiter 10 gallons et utilisera la pompe 5 secondes, etc. Lorsque la voiture est alimentée, elle part et l'autre voiture peut utiliser la pompe . Après avoir alimenté une voiture, la quantité de carburant dans la pompe est ajustée en conséquence.
- Si les deux pompes sont actuellement utilisées, une voiture qui arrive attend que l'une des deux pompes devienne disponible.
- Si une pompe manque de carburant, elle doit attendre qu'un pétrolier fournisse plus de carburant. Le pétrolier arrive périodiquement (mais pas trop souvent) et remplit les deux pompes à pleine capacité. Pendant qu'un camion ravitaille les pompes, aucune voiture ne peut utiliser les pompes. oublié d'ajouter ceci

Partie I: vous devez soumettre une conception détaillée qui correspond aux spécifications ci-dessus. Votre conception doit utiliser des threads Java. Vous devez spécifier le nombre et le type de threads que vous utiliserez et comment ces threads seront synchronisés. Vous pouvez écrire cette étape du projet en pseudo-code. C'est pour vous aider à comprendre comment les différentes pièces vont ensemble.

Partie II: vous devez soumettre une implémentation complète de votre conception en utilisant des threads Java et des méthodes de synchronisation appropriées. Votre implémentation doit être soigneusement testée par rapport aux spécifications ci-dessus.


Je veux savoir. Comment puis-je utiliser un thread Java pour simuler les voitures arrivant à des intervalles aléatoires?
Je suis très perdu et j'apprécie votre aide à l'avance.

+2

L'utilisation de plusieurs threads est-elle une exigence? Je ne pense pas que ce soit une bonne situation pour utiliser des threads, mais bien sûr si le but est d'apprendre à travailler avec des threads, cette critique ne s'applique pas. – CodesInChaos

+0

oui je pense que j'ai besoin d'utiliser plusieurs threads. – Luron

+0

Oui, je suis d'accord, pas une bonne situation pour les discussions. Mais alors c'est juste pour apprendre l'intérêt. – Matt

Répondre

12

Créer une classe d'usine automobile qui crache une voiture à ajouter à une dequeue et va dormir pendant une période aléatoire.

Comme tous les étudiants, vous trouvez probablement ce problème un peu écrasant. C'est si vous ne commencez pas à le décomposer en plus petits morceaux que vous pouvez gérer. Pensez à un design global et commencez à en implanter de petites pièces.

Par exemple, il s'agit d'un problème de théorie des files d'attente. Ils pourraient être des voitures, des gens dans les lignes de banque, ou tout ce qui interagit avec une file d'attente. Ne vous inquiétez pas pour les voitures ou les détails de la station d'essence. Voici votre problème:

  1. Vous avez une ligne qui ajoute de nouvelles entrées à une extrémité et les enlève à l'autre.C'est ce qu'on appelle une structure de données dequeue. Lisez à ce sujet. Voyez si vous pouvez écrire (ou réutiliser) une classe Java Dequeue. Comprends-le complètement. Ecrire un petit pilote à ajouter à une extrémité et retirer de l'autre.
  2. Une fois que vous avez cela, vous devez écrire des classes qui créent de nouvelles entrées à ajouter à la dequeue et une autre pour les supprimer. Commencez simplement en écrivant des additionneurs/dissolvants qui fonctionnent à intervalle fixe. Ce que vous devriez voir, c'est que si l'additionneur et le déménageur ont exactement la même interface, le nombre d'entrées en attente ne changera pas. Si l'additionneur travaille plus vite que le solvant, la ligne devrait se remplir. Si le déménageur fonctionne plus vite que l'additionneur, vous n'aurez jamais de sauvegarde. Assurez-vous que vos classes simples présentent ce genre de comportement.
  3. Ajoutez les bits aléatoires et lancez votre simulation. Vous voulez voir comment le nombre d'entrées dans la ligne change au fil du temps.
  4. Ajoutez maintenant plus d'une ligne. Vous voulez voir comment ajouter plus de lignes change la dynamique.
+0

Thread.currentThread(). Sleep (1000) – Dlongnecker

+0

1000 n'est pas aléatoire; c'est un chaque seconde. – duffymo

+0

puis-je faire Random r = new Random(); Thread.currentThread(). Sleep (r.nextInt (100000)) – Luron

3

Si vous avez des intervalles fixes, le nombre de voitures arrivant dans cet intervalle est Poisson distribué.

Le temps entre deux voitures a une probabilité proportionnelle à exp (-t/tau) où tau décrit la fréquence d'arrivée des voitures. Vous avez donc besoin de comprendre comment créer des nombres aléatoires distribués exponentiellement. A partir d'une densité de probabilité de p (t) = c * exp (-t/tau), nous intégrons une distribution de probabilité cumulative de P (t) = 1-exp (-t/tau). Donc, en inversant cette fonction, vous obtenez t = -tau * ln (1-P (t)). Donc, si vous générez un nombre uniformément réparti entre 0 et 1, vous pouvez obtenir une distribution correcte t comme t = -tau * ln (1-u)

+0

La distribution de Poisson est définitivement ce que vous voulez. –

+0

Comment la distribution de Poisson est-elle liée à la résolution du problème du PO? C'est-à-dire 'Comment utiliser un thread Java pour simuler les voitures arrivant à intervalles aléatoires?' –

+0

Pour un exercice en classe, je commencerais par une distribution uniforme en utilisant 'Random' pour générer des nombres. Une fois que cela fonctionne, optez pour un Poisson pour les crédits supplémentaires. – Qwerky

0

Vous pouvez utiliser le même type de source de voitures. Vous pouvez établir un intervalle de temps par exemple avec un écart aléatoire.

1

Je peux voir où vous allez avec un fil, mais vous n'en avez pas vraiment besoin sauf s'il s'agit d'une simulation graphique dans laquelle vous souhaitez que les gens le voient fonctionner en temps réel. Sinon, il suffit de suivre une chronologie. Savoir à un moment donné quel événement va se produire ensuite entre: A) Le camion arrive. B) La voiture arrive. C) Les feuilles de voiture.

J'imagine que vous gardez une trace de combien de temps ces choses prennent, donc simuler simplement l'événement à se produire plus tôt. Et chaque fois qu'une voiture arrive, le temps nécessaire à l'arrivée d'une nouvelle voiture sera un temps aléatoire décidé par vous.

Croyez-moi, ça va rendre la vie beaucoup plus facile pour vous simplement.

+0

oublié d'ajouter ceci *** Partie I: vous devez soumettre un design détaillé qui correspond aux spécifications ci-dessus. Votre conception doit utiliser des threads Java. * Vous devez spécifier le nombre et le type de threads que vous utiliserez, et comment ces threads seront synchronisés. Vous pouvez écrire cette étape du projet en pseudo-code. C'est pour vous aider à comprendre comment les différentes pièces vont ensemble. ** Partie II: vous devez soumettre une implémentation complète de votre conception en utilisant des threads Java et des méthodes de synchronisation appropriées. Votre implémentation doit être soigneusement testée par rapport aux spécifications ci-dessus. – Luron

+0

Eh bien, si c'est un exercice sur l'utilisation de threads Java, vous devriez le faire. Cependant, sachez que ce n'est pas un scénario approprié pour un thread dans un contexte pratique. – Neil

0

Vous pouvez utiliser le PriorityBlockingQueue thread-safe pour créer une file d'attente d'événements. Fondamentalement, les arrivées de voitures, les arrivées de camions-citernes, les voitures qui entrent dans la pompe et la voiture qui sort d'une pompe sont tous des événements. Chacun d'entre eux ayant un ordre d'occurrence, vous insérez un objet "Event" pour chacun de ces événements, avec un horodatage. Vous pouvez faire en sorte que l'horodatage soit utilisé par PriorityBlockingQueue pour trier les événements. Initialement, vous démarrez un thread pour le thread producteur de l'arrivée de la voiture et le thread producteur de l'arrivée du tanker. Le thread d'arrivée de la voiture put() un CarArrivalEvent à la file d'attente, puis de dormir pendant une durée aléatoire. Le fil du tanker fait également la même chose, mais put() TankerArrivalEvent à la place.

La station d'essence a deux pompes, chacune représentée par des fils de consommation. Chaque thread de la pompe sera un événement CarArrivalEvent, puis de dormir pendant le temps nécessaire pour remplir la voiture. Vous faites de même pour TankerArrivalEvent.

0

N'utilisez pas de distribution de Poisson. La Poission vous donnera "Nombre d'arrivées dans les X minutes suivantes". Cela ne vous donnera pas "Temps jusqu'à la prochaine arrivée".

Wite une petite boucle while comme si ::

public int getTimeTillNextCar() { 
    PROBABILITY = .001; 
    int timeTillNextCar = 0; 
    while(rand.nextDouble() > PROBABILITY) { 
     timeTillNextCar++; 
    } 
    } 

De toute évidence, je supposais que vous utilisez le temps discret. Cependant, il est possible (et certains diront mieux) d'utiliser un seul tirage à partir d'une exponentielle. Ce sera plus efficace. Cependant, utiliser cette approche rend le code "mathy" que certaines personnes pourraient ne pas aimer.

Rappelons que la distribution de Poisson provient du comptage du nombre de tirages bernoulli réussis étant donné n tirages lorsque p est très petit et n est modérément grand. Si n est "trop" grand alors la distribution de Possion convergera vers la distribution normale.

Comme pour le reste de la conception ...

Thread_A devrait ajouter des voitures à une file d'attente (assurez-vous d'utiliser un thread-safe classe de file d'attente)

Thread_A shoule faire:
ajouter voiture,
sommeil (getTimeTillNextCar()),
voiture add,
sommeil (getTimeTillNextCar()),
ajouter voiture,
sommeil (getTimeTillNextCar()),
etc ....

Thread_B et Thread_C devraient prendre voitures de la file d'attente:
Thread_B (et C) devraient faire:
get_car_off_queue,
sommeil (car.getFuelingTime(),
get_car_off_queue,
sommeil (car.getFuelingTime(), etc ...

+1

Si vous avez deux threads représentant les pompes, alors cela ne correspond pas à la spécification du problème - le problème dit que "si une pompe est disponible et a du carburant, la voiture est immédiatement autorisée à l'utiliser". Si vous ne courez pas dans un RTOS, il n'y a aucune garantie que le thread pour une pompe gratuite sera programmé et dequeue une voiture. –

+0

Pete Kirkham, dans une maison ... – duffymo

+0

@Pete - Vrai, mais c'est un problème assez facile à résoudre. La gestion du cas "pas de file d'attente" ne va pas faire dérailler cette configuration générale. – Ivan

1

Tout d'abord, car il n'y a rien dans votre OP soit ni le bit supplémentaire de l'énoncé du problème qui stipule que le système fonctionne contre l'horloge murale, don Je suppose que c'est le cas. Quelque chose basé sur dormir pendant dix secondes entre la création de voitures vous rendra fou pendant que vous le tester. Créer une interface simple pour donner du temps pour la simulation et travailler contre cela; Si vous avez besoin de l'attacher à l'horloge murale, alors vous pouvez, mais vous pouvez également exécuter vos tests aussi vite que votre machine ira. Deuxièmement, il est généralement préférable de faire des simulations en tant qu'évènements - la voiture arrive à la gare, les voitures passent de la file d'attente à la pompe, la voiture sort de la pompe et le camion arrive. Habituellement, une file d'attente prioritaire d'événements basée sur leur temps fonctionne; Quand une voiture commence à se remplir, vous ajoutez l'événement pour qu'il complète sa tâche dans la file d'attente des événements avec un horodatage dans le futur. C'est beaucoup, beaucoup plus facile d'écrire de la logique pour ne pas traiter les voitures s'il y a un tanker à un moment donné plutôt que de se moquer des priorités de threading. Puisque votre tâche nécessite que vous démontriez une certaine synchronisation entre les threads, vous pourriez vouloir exécuter les processus de wagons en attente, les wagons remplissant/déchargeant des wagons-citernes en threads séparés (dans le vrai logiciel vous ne le feriez pas, mais plus probablement un exécuteur si vous vouliez une exécution parallèle, mais je suppose qu'il s'agit d'une tâche pédagogique et que vous devez montrer un peu de conception de threads, plutôt que de laisser la bibliothèque trier tout cela pour vous).

Ainsi, pour chaque tranche de temps, vous traitez les événements de la file d'attente, attendez que tout le traitement de l'événement se termine, puis demandez à l'horloge la coche suivante. L'horloge rapide renvoie immédiatement un horodatage pour la seconde suivante, ou une horloge murale attend jusqu'à la seconde suivante de l'heure système. Etant donné que vous devez utiliser des threads pour chaque tâche, vous devez synchroniser ces tâches au début et à la fin de chaque tranche de temps. Vous devez synchroniser ou vérifier que les événements mis en file d'attente sont mis en file d'attente et visibles avant un fin de tranche de temps.

Ainsi, les tâches sont quelque chose comme:

  • voitures entrantes

    • chaque seconde, déterminer le nombre d'arrivées de voiture. ce sera une distribution de Poisson.
    • (alternativement, utiliser un autre mécanisme aléatoire, la plupart des autres approches ne feront qu'arriver à une voiture à la fois, ce qui est pas souvent une restriction utile de placer sur un modèle)
  • tankers entrants

    • tous (période d'arrivée des navires-citernes) poster un événement arrivé citerne par pompe
  • voitures attente

    • d'augmenter le nombre de voitures en attente sur l'événement d'arrivée de voiture
  • Pompes

    • si un camion-citerne est arrivé, mis le camion-citerne attendant drapeau
    • si la la pompe est libre, puis
      • si un pétrolier attend, réinitialiser l'indicateur d'attente du bateau-citerne, remplir la pompe, signaler l'éventualité d'une pompe à vide dans le futur
      • si la pompe a du carburant et qu'une voiture attend, décrémentez le nombre de voitures en attente à remplissage voiture à l'avenir

l'énoncé du problème est pas clair si le navire-citerne doit attendre les deux pompes soient libres avant de pouvoir commencer à les remplir, dans ce cas, vous besoin d'ajouter un autre état «tanker ready». Si les tâches se trouvent dans des threads différents, vous devez synchroniser les différents compteurs, soit manuellement, soit en utilisant les valeurs atomiques dans java.util.concurrent.atomic.

Questions connexes