Message Boards Message Boards

OOP evaluation for Multi-agent model exampled from Wolfram Demonstration

Posted 7 years ago

This project is to illustrate the Mathematica OOP power for the multi-agent models picking up the examples. In this time, selected example is "3D Boid Model" presented by Jake Zhang from the Wolfram Demonstration Project.

The multi-agent system suits to OOP because each agent can be represented by an instance constructed from the agent class. For this boid model, OOP advantage can be found in simple code structure because each boid behavior is controlled by the instance which has local parameters such as boid position, velocity, however, the advantages on the computation time was not clear, because the most computation time is consumed by the calculation of distance between two boids.

First part is the class definition.

zero = {0., 0., 0.};
rNeighbor = 10^2;
rCollision = 5^2;
vR = 2.0;

SeedRandom["boid"];
boidClass[agents_] := Module[
   {pos, posNew, velocity, dVelocity, velocityNew,
    pList, nList, cList
    },
   initBoid[agents] ^:= (
     pos = {RandomReal[{0, worldSize}], RandomReal[{0, worldSize}], 
       RandomReal[{0, worldSize}]};
     velocity = 
      vR*Apply[{Cos[#1] Cos[#2], Cos[#1] Sin[#2], 
          Sin[#2]} &, {RandomReal[{0, 2*Pi}], 
         RandomReal[{0, 2*Pi}]}];
     );
   getBoidPos[agents] ^:= pos;
   getBoidVelocity[agents] ^:= velocity;

   nextStep[agents[agentList_]] ^:= (
     pList = 
      Map[SquaredEuclideanDistance[pos, #] &, 
       Map[getBoidPos[#] &, agentList]];
     cList = Flatten@Position[pList, _?(0 < # < rCollision &)]; 
     nList = Complement[Flatten@Position[pList, _?(# < rNeighbor &)], 
       cList];

     dVelocity =
      (0.2 velocity
        + 
        If[nList == {}, 
         zero, (0.3 Normalize[
             Mean[Map[getBoidVelocity[#] &, agentList[[nList]]]]]
            + 
           0.2 Normalize[
             Mean[Map[getBoidPos[#] &, agentList[[nList]]]] - pos])
         ]
        + 
        If[cList == {}, zero, 
         0.3 Normalize[
           pos - Mean[Map[getBoidPos[#] &, agentList[[cList]]]]]]);

     velocityNew = vR*Normalize[dVelocity];
     posNew = pos + velocityNew;

     );
   renewBoid[agents] ^:= (
     pos = Mod[posNew, worldSize, 1];
     velocity = velocityNew;
     );
   drawBoid[agents] ^:= 
    Graphics3D[{Cylinder[{pos, pos + 0.1 velocity}], 
      Line[{pos, pos + 3. velocity}]}];
   ];

Second part is the manipulate section.

Manipulate[
 (If[i == 1,
   objectList = Table[Unique[], {num}];
   Map[boidClass[#] &, objectList];
   Map[initBoid[#] &, objectList];
   Show[Map[drawBoid[#] &, objectList], 
    PlotRange -> {{0, wsz}, {0, wsz}, {0, wsz}}, 
    ImageSize -> {400, 400}],

   Map[nextStep[#[objectList]] &, objectList];
   Map[renewBoid[#] &, objectList];
   Show[Map[drawBoid[#] &, objectList], 
    PlotRange -> {{0, wsz}, {0, wsz}, {0, wsz}}, 
    ImageSize -> {400, 400}]]),

 {{vR, 2, "velocity"}, 0.5, 5, ImageSize -> Tiny},
 {{num, 50, "number of Boids"}, 1, 300, 1, ImageSize -> Tiny},
 {{wsz, 100, "world size"}, 50, 200, 1, ImageSize -> Tiny},
 {{i, 1, ""}, 1, \[Infinity], 1, ControlType -> Trigger}, 
 SaveDefinitions -> True, AutorunSequencing -> {2, 3}, 
 ControlPlacement -> Left]
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract