Re: 3D Agent Problem
- To: mathgroup at smc.vnet.net
- Subject: [mg99006] Re: [mg98979] 3D Agent Problem
- From: Daniel Lichtblau <danl at wolfram.com>
- Date: Fri, 24 Apr 2009 03:44:14 -0400 (EDT)
- References: <200904231042.GAA24510@smc.vnet.net>
Earl.J.Mitchell at gmail.com wrote: > Hi, > > I am trying to set up a 3D environment having 'agents' and 'stuff' whose > coordinates are random real numbers. > > The program should then move the agents towards the closest stuff in > increments of, say, .1 units. > > I was able to create a program that did what I need for one iteration, but > am having problems making it iterative... below is the code. I'm > inexperienced and learning quickly but would really appreciate any guidance > on iterating this system. > > ***************** > Making a World of Agents and Stuff > > MakeNewWorld[Agents_] := > Partition[Flatten[ > Riffle[Table[RandomReal[{-10, 10}, {Agents, 3}]], > Table[RandomInteger[9, 3], {Agents}]]], 6, 6] > > MakeNewStuff[Resources_] := Table[RandomReal[{-10, 10}, {Resources, 3}]] > > agentpos1 = MakeNewWorld[10][[All, 1 ;; 3]]; > stuffpos1 = MakeNewStuff[5]; > > ListPointPlot3D[{agentpos1, stuffpos1 }, PlotStyle -> PointSize[Large]] > > ***** 3D plot of agent positions and stuff positions ******* > > The Problem of Movement > > Agents search for nearest stuff and move along the vector between their > current position and that of the stuff. > > Ax = agentpos1[[All, 1]]; > Bx = stuffpos1[[All, 1]]; > Ay = agentpos1[[All, 2]]; > By = stuffpos1[[All, 2]]; > Az = agentpos1[[All, 3]]; > Bz = stuffpos1[[All, 3]]; > > dx = Part[Ax, #] - Bx &; > dy = Part[Ay, #] - By &; > dz = Part[Az, #] - Bz &; > > TOTdx = dx /@ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; > TOTdy = dy /@ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; > TOTdz = dz /@ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; > > squared = #^2 &; > > distance = (squared /@ TOTdx + squared /@ TOTdy + squared /@ TOTdz)^.5; > > mindistance = Min /@ distance; > > stufffinder = Flatten[Position[distance, #]] &; > > stuffpositions = Flatten[stufffinder ] /@ mindistance; > > newstuff = stuffpositions[[All, 2]]; > > coords = Part[stuffpos1, #] &; > > stuffcoords = coords /@ newstuff; > > WalkFunct2 = > If[Part[Flatten[agentpos1], #] < Part[Flatten[stuffcoords], #], > Part[Flatten[agentpos1], #] + .5, Part[Flatten[agentpos1], #] - .5] &; > > newagentcoords = > WalkFunct2 /@ {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, > 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}; > > agentpos2 = Partition[newagentcoords, 3, 3, {1, 3}]; > > ListPointPlot3D[{agentpos2, stuffpos1 }, PlotStyle -> PointSize[Large]] > You are making this more complicated than necessary by focussing on breaking apart things into coordinates rather than operating on the lists as entire entities. Also some of the initialization code suffers from a bit of funk. I instead proceed as below. makeNewWorld[agents_] := Apply[Join, Partition[ Riffle[RandomReal[{-10, 10}, {agents, 3}], RandomInteger[9, {agents, 3}]], 2], 1] makeNewStuff[resources_] := RandomReal[{-10, 10}, {resources, 3}] agentlocations = makeNewWorld[10][[All, 1 ;; 3]]; stufflocations = makeNewStuff[5]; To iterate the incremental moves you could use NestList. One way to code this is shown below. Notice that all the action takes place in just a few lines. steplist = NestList[Function[{ll}, (distances = Outer[Norm[#1 - #2] &, ll, stufflocations, 1]; stuffpositions = Map[First[Ordering[#, 1]] &, distances]; stuffcoords = stufflocations[[stuffpositions]]; steps = .1*Sign[stuffcoords - ll]; ll + steps)], agentlocations, 60]; This next provides a simple way to vislauize the incremental moves as agents approach stuff. Manipulate[ ListPointPlot3D[{steplist[[j]], stufflocations}, PlotStyle -> PointSize[Large]], {j, 1, Length[steplist], 1}] Note that our incremental moves have discrete size of 0.1 and so we eventually get to locations where agents will step back and forth in the vicinity of the stuff. I assume this is the sort of thing you intend to refine later. Speaking of refinements, it might get quite interesting if agents also sense proximity of other agents, so they can adjust their notion of "nearest" to maybe move toward things that are not objects of great desire. (Okay, this would NEVER happen in the real world...) By the way, that NestList can be compactified, though doing so makes it ever the more difficult to follow. Anyway, for those who like such things, the variant below works. steplist = NestList[# + Sign[ stufflocations[[Map[First[Ordering[#, 1]] &, Outer[Norm[#1 - #2] &, #, stufflocations, 1]]]] - #]/10. &, agentlocations, 60]; I'd imagine one could squeeze still further. The main reason to do this is to avoid use of global variables, and a cleaner approach would be to skip compactification and put the whole mess inside a Module. Daniel Lichtblau Wolfram Research
- References:
- 3D Agent Problem
- From: Earl.J.Mitchell@gmail.com
- 3D Agent Problem