Dans une simulation, les travailleurs doivent se déplacer autour d'une carte effectuant des tâches. P>
Chaque simulation 'tick', ils peuvent déplacer un carré. P>
Effectuer la tâche une fois qu'ils sont adjacents à cela prend 10 ticks. P>
Les carrés de tâches ne peuvent pas être transmis. Les carrés avec des travailleurs ne peuvent pas être passés. Plus d'un travailleur peut travailler sur un carré. P>
Les travailleurs ne sont pas en compétition les uns avec les autres; L'objectif est de compléter toutes les tâches le plus rapidement possible. P>
ajouté: strong> Idéalement, l'algorithme doit être simple à conceptualiser et à mettre en œuvre simple. N'est-ce pas ce que tout le monde veut? C'est un grand avantage si son E.G E.G. Le modèle peut être mis à jour et réutilisé plutôt que recalculé de zéro souvent. Idéalement, il sera capable d'utiliser Optima local afin de ne pas essayer de brutter un problème de NP, mais d'éviter d'être gourmands et de réfléchir un peu, plutôt que des errances essentiellement aléatoires où les travailleurs paient peu des plans des autres. < / p>
Voici un exemple: p>
Les travailleurs 1 et 2 doivent compléter les tâches sur les carrés A, B, C et D. P>
Comment décidez-vous quel travailleur fait quelle tâche? P>
Il semble évident que 1 devrait faire A et 2 devraient faire c. p>
1 est de 4 carrés d'A, alors vous aurez fini de le faire en 14 ticks. Où devrait-il aller ensuite et pourquoi? P>
Et quoi s'il y avait une autre tâche - E - est placé directement au-dessus de B? p>
Quelle est la logique qu'un travailleur utilise pour décider où procéder ensuite? P>
Qu'est-ce que j'ai essayé: p>
Ceci étant un jeu de RTS de Hobby, j'ai essayé de le faire si des travailleurs inutiles passent à la tâche la plus proche ou de passer à la tâche la plus proche qu'aucun autre travailleur. P>
Cette approche gourmande s'est révélée entrer dans l'inefficacité et que les tests de joueurs indiquent que cela clarifie son intenable. Étant donné que l'exploitation minière / bâtiment / agriculture stratégique est la clé du jeu, et parce que je ne veux pas que le joueur de micro-gérance et acheminez tous les travailleurs, je recherche un algorithme assez équitable et raisonnablement optimal que les travailleurs peuvent utiliser à la place. p> p>
8 Réponses :
Même avec un ouvrier, il s'agit d'un problème d'optimisation complet de NP-complet (il devient alors le problème du vendeur itinérant) alors oublions donc "optimal". p>
Si vous savez que le travailleur 1 traitera des tâches A1, A2, ..., travailleur 2 traitera les tâches B1, B2, ... et ainsi de suite, vous pouvez, après cette décision, essayez de résoudre le problème. Problèmes de vendeurs de voyage indépendants un par un, et vous obtenez les horaires et les chemins de tous vos travailleurs. P>
Cependant, le problème est que vous ne pouvez pas savoir combien de temps il faut pour compléter un ensemble de tâches A1, A2, ... pour un travailleur avant d'avoir résolu le problème du vendeur itinérant pour cet ensemble, car le temps de marche a une incidence sur le temps de la marche. temps total pour effectuer les tâches. P>
Parce que c'est juste un jeu et que les travailleurs peuvent être supposés être des penseurs optimaux, j'utiliserais un processus stochastique: p>
+1 J'étais sur le point de suggérer la même chose.
J'aime cette réponse d'un point de vue scientifique. Avec les connaissances supplémentaires dont nous parlons de jeu, je suis un peu désactivé si cette idée s'amusera aux joueurs à cause de plusieurs raisons. "Incertain" signifie que je doute un peu et peut-être que j'ai raison, peut-être pas. J'aime toujours l'approche du problème en général.
Parce que c'est un jeu RTS, j'essaierais de choisir une approche simple, rapide et facile à comprendre. P>
Tout d'abord, bien sûr, j'essaierais l'approche gourmande. Mais vous avez déjà mentionné que cela ne fonctionne pas. P>
Ensuite, j'essayerais quelque chose comme un algorithme gourmand de second ordre. Chaque travailleur choisit la tâche la plus proche A, puis choisit les tâches les plus proches B à côté de A. Ils essaient (!) Pour choisir des tâches, personne n'a choisi jusqu'à présent. Quelque chose comme ça. P>
Gardez-le petit et simple. Et vous pensez: Peu importe quel algorithme vous avez choisi, là
Cela sonne bien beaucoup comme le problème du vendeur (déjà mentionné) Problème de vente (TSP, http://fr.wikipedia.org/ wiki / travell_salesman_problem ) pour plusieurs agents. Ce qui est en fait un problème similaire à plusieurs sacs à dos (MKP, http://fr.wikipedia.org/wiki/knapsack_problem#multiple_knapsack_problem < / a>) ou même emballage bin ( http://fr.wikipedia.org/wiki/bin_packing_problem ). p>
Il existe un groupe d'algorithmes qui pourraient convenir à cette situation, et on l'appelle «optimisation de la colonie des fourmis» (ACO, HTTP : //fr.wikipedia.org/wiki/ant_colony_optimization_algorithms ). P>
combiner les deux, il existe des implémentations qui utilisent ACO pour résoudre des problèmes MKP; Cela semble être un bon moyen d'aller dans ce cas, par exemple: P>
Je suggérerais quelque chose de similaire à APPROCHE TOBIMCAMOBI 'S, mais plus raffinée: p>
z code> il faudra pour terminer cette file d'attente. Li>
- Donnez à chaque tâche une propriété
d code>, définie sur 0. Cela signifie combien cette tâche "est déjà traitée" en fonction du plan actuel. LI>
- Répéter jusqu'à ce que tous les travailleurs ont au moins un emploi
et strong> ( z code >> une valeur fixe ou strong> une quantité de temps donnée a passé):
- Prenez l'un des travailleurs
w code> avec minimal z code>.
- SET
p code> à la position de la dernière entrée de la file d'attente w code> S ou w code> s
la file d'attente est vide. li>
- boucle sur les tâches non dans cette file d'attente des travailleurs en ordre de distance avec
p code>
- Calculez
Distance / D CODE> LI>
- Si vous trouvez un minimum pour cette valeur, ajoutez cette tâche à la file d'attente du travailleur, ajoutez la distance à la tâche + 7 à
z code> et ajoutez 1 / z code> à d code>. Casser la boucle. Li>
ul> li>
ul> li>
ul> li>
ul>
Avant de l'exécuter, vous devez trier les travailleurs en fonction de la distance à la tâche la plus proche. Sinon, la première tâche est donnée assez au hasard et la première tâche est la plus importante. P>
Vous pouvez mettre à jour cela chaque fois qu'un travail ou un travailleur est ajouté. Réutiliser certaines des valeurs précédentes (peut-être stocker des résultats intermédiaires, comme l'ajout de la correspondance z code> aux tâches de la file d'attente du travailleur), cette mise à jour doit être plutôt rapide. P>
Cela doit également être mis à jour une fois de temps en temps, car cet algorithme devient assez inexact une fois que vous allez assez loin dans l'avenir. P>
Le Distance / d Code> La formule peut également avoir besoin de quelque résled, mais je suppose que des tests aideraient beaucoup ici. P>
La définition de "minimum" est à vous de décider. Je recommanderais de prendre un Minumum local, peut-être vérifier 5 tâches supplémentaires au maximum. Trouver le minimum mondial semble inutilement coûteux. P>
La façon dont vous avez présenté votre réponse est un modèle à d'autres réponses! :RÉ
Au lieu d'assigner gourmandeusement les travailleurs à la tâche la plus proche, essayez d'assigner la tâche de gourmandise à son ouvrier «le plus proche», c'est-à-dire que le travailleur dont le chemin passe de près et a suffisamment de temps perdu pour le gérer. De cette façon, vous avez une notion (gourmande) du plus petit temps nécessaire pour compléter toutes les tâches.
Par exemple: P>
D est la «tâche la plus éloignée», même sans définir ce terme encore, donc attribuer D à 1. Il est de 15 + 10 unités, donc définissez Voici le coût de la distance Tâche suivante, en prenant en compte les itinéraires les plus courts. p> mais voici le coût réel en fonction de l'idée gourmande; l'augmentation du temps maximum car c a le coût le plus élevé (c'est la tâche la plus dangereuse d'une perspective gourmande),
Attribuez C à 2. P> Les coûts suivants sont les suivants: P> t code> = 25 et le relâché sur 2 à 25. p>
t code>. p>
A B slack A B
1 10 22 0 10 22
2 21 11 (-)7 14 4
(Remarque: après tout cela, je vous rends compte que vous avez dit que vous avez dit 14 ticks car par "adjacent" que vous pensais "au-dessus de" pendant que je l'ai interprété comme "à côté" ... Alors gardez à l'esprit mes calculs sont basés sur mes calculs. cela, mais cela ne devrait pas changer le résultat de beaucoup.)
Mon premier instinct serait de créer d'abord une file d'attente indépendante pour chaque travailleur en fonction du temps optimal à compléter, en supposant qu'aucun autre travailleur n'existe et ne traite pas des conflits plus tard ( Notez que, selon mon interprétation, lorsque 1 est terminé avec A, alors B est plus proche que d que d, mais une chose essentielle que nous voulons empêcher est 1 prise B): P>
1 [A=13, D=24] 2 [C=17, B=28]
Je suppose que la gourmandise "en temps réel" s'avère être mauvaise, car les travailleurs se retrouvent sur la chasse à l'oie sauvage vers des tâches qui seront complètes ou presque donc au moment de leur arrivée. Je vais donc proposer un algorithme de planification: un moyen d'attribuer intelligemment chaque travailleur à une séquence de tâches où l'Union des séquences est une couverture.
Comme d'autres ont déclaré que le TSP est intégré à cette condition de planification, c'est donc un NP Problème dur. P>
Mais il y a un algorithme d'approximation de temps polynomial facile pour le TSP qui produit un chemin d'accès maximal de 2x de longueur optimale. Il suffit de calculer une arborescence minimale étendue comprenant tous les sites de travail plus l'un des travailleurs. Ensuite, le chemin évident traversant chaque bord une fois dans chaque direction touche chaque nœud. P>
Bien sûr, lors de la mise en route Vous pouvez "abeilles-line" passé déjà visité des nœuds. Cela signifie simplement émettre la séquence de tâches en parcourant le MST en pré-commande. En raison de l'inégalité du triangle, ce chemin est souvent un peu meilleur que 2 fois optimal. (Je suppose que les mesures diagonales sont autorisées ici. Sinon, ce n'est pas vrai, mais l'algorithme fonctionne toujours bien.) P>
Donc, une approche de la planification est la suivante: P>
Dans l'algorithme ci-dessous, les événements incluent une heure d'apparition projetée et sont placées sur la file d'attente d'événement avec cette fois-ci comme clé. P>
Let Arrive(W, T, L) be an arrival event of worker W at task T starting from previous location L, traveling the shortest path Let Complete(W, T) be a completion event for worker W of task T For each worker W, place Arrive(W, T_W1, S_W) on the queue While events are left on the queue Remove an event E If E is an arrival Arrive(W, TW_i, L) If TW_i has no worker yet, Assign TW_i to W Schedule a future event Complete(W, TW_i) 10 time units in the future. Else // T has a worker Schedule Arrive(W, TW_{i+1}, L), if TW_{i+1} exists Else E is a completion Complete(W, TW_i) Schedule Arrive(W, TW_{i+1}, TW_i), if TW_{i+1} exists
Une explication très claire; Je l'ai travaillé dans ma tête pour quelques scénarios et cela semble fonctionner. C'est l'approche que je vais mettre en œuvre.
@Will Cool. Revenez s'il vous plaît pour dire comment il s'est avéré!
Je suppose que l'apparition des travailleurs a besoin de ressembler à ce qu'un humain ferait (l'algorithme doit affecter chaque travail en tant que potentiel humain). Si l'algorithme ne le fait pas, un joueur se demandera ce que l'IA est faire et probablement essayer de parcourir manuellement (même s'il est moins optimal). Je pense que toute solution "globe optimale" ne ressemblerait probablement pas à ce qu'un humain ferait ... p>
Donc, je dirais que votre algorithme initial (volonté) pourrait avoir une légère amélioration du travail. Laissez chaque travailleur se diriger vers le travail de vaccant le plus proche, mais simulez-le là-bas et arrêtez la simulation lorsque le travailleur atteint le travail ou un autre travailleur est gratuit qui est plus proche (alors que le travailleur prendra ce travail). Si aucun emploi de vaccant ne peut être atteint, choisissez le travail occupé le plus proche et y aidez-y. P>
Cela ressemble à une variation de The Tsp .
Il est plus lié à Multi Agent et distribué AI que le TSP. Il a de nombreux paramètres comme combien chaque travailleur peut voir, avez-vous un nœud central ou pas et tant d'autres choses. Vous devez déterminer les spécifications d'environnement, puis proposer une solution.
Suis-je raison pour que de nouvelles tâches puissent apparaître à tout moment, quelles que soient les autres tâches et que vous souhaitez des tâches de mise à jour rapidement lorsque cela se produit?
@Jordangray absolument. Les tâches peuvent également être supprimées de la liste des tâches par l'utilisateur.
J'ai une question. Puisqu'il n'y a pas de solution directe pour votre problème (c'est TS) pourriez-vous peut-être élaborer sur vos meilleurs et les plus pires scénarios pour différents travailleurs? Par exemple, quel est le montant maximum de nœuds qu'un travailleur devra frapper? Combien de travailleurs simultanés regardons-nous?
Cross posté après ne pas avoir reçu les réponses qu'ils voulaient: GameDev.StaCKeXchange.com/questions / 61726 / ...
Essayez toutes les possibilités!