0

I am new to Anylogic, and would like to perform the following task. I have several types of immobile agents on a GIS environment and would like to connect them by a network. The condition for the connections is as follows: Let agent type A has 4 agents and agent type B has 20 agents. I want to connect B with A based on the shortest (straight line) distance. That is, an agent of type B is to be connected to the nearest agent of type A.

Thank you.

1 Answers1

0

In your specific case, this is what you want at the beginning of your model:

// For each of your Bs
for (Agent B : populationOfB) {
  // Find the nearest A (using a straight line) and connect.
  B.connections.connectTo(B.getNearestAgent(populationOfAgentA));
}

More generally, if you want a B to be connected to multiple A agents that match a particular set of conditions and you need to do that on the fly (or at the start of the model), you can do the following:

// For each B
for (Agent B : populationOfB) {

  // Find all A agents that it could possibly connect with.
  // Every time we take an agent from this collection, it will shrink to ensure we don't keep trying to connect to the same A.
  List<Agent> remainingOptions = filter(

    // We start with the full population of A
    populationOfAgentA, 

    // We don't want B to connect with any A it's already connected to, so filter them out.
    A -> B.connections.isConnectedTo(A) == false

      // You might want other conditions, such as maximum distance, some specific attribute such as affordability, etc.; simply add them here with a "&&"
      /* && <Any other condition you want, if you want it.>*/
  );

  // If B ideally wants N connections total, we then try to get it N connections. We don't start i at zero because it may already have connections.
  for (int i = B.connections.getConnectionsNumber(); i < N; i += 1) {

    // Find the nearest A. (You can sort based on any property here, but you'd need to write that logic yourself.)
    Agent nearestA = B.getNearestAgent(remainingOptions);

    // Connect to the nearest A.
    B.connections.connectTo(nearestA);

    // The A we just connected to is no longer a valid option for filling the network.       
    remainingOptions.remove(nearestA);

    // If there are no other remaining viable options, we need to either quit or do something about it.
    if (remainingOptions.isEmpty()) {
      traceln("Oops! Couldn't find enough As for this B: " + B);
      break;
    }
  }
}

Also note that I use connections a lot: you could substitute that for a more specific network if you need multiple collections such as work, school, and social networks.

Dylan Knowles
  • 2,726
  • 1
  • 26
  • 52
  • I really appreciate your response. When we use connectTo(agent) method, I realized that it create bidirectional connections. However, I am in a situation where I need to connect A to B for purpose 'x' and B to A for purpose 'y'. connectTo() doesn't reallt work here. Have you come across any solution for this? Thank you. – Srijith Balakrishnan Mar 22 '17 at 17:33
  • Try creating a unique "Link to Agents" in A and B, and then check the option to make sure it's unidirectional. Let's pretend its called `employer` in A. You can then say things like `myAgentA.employer.connectTo(myAgentB)`. If you check the "single link" option, you guarantee that there is only ever a single connected B. This said... this is overly complicated. Why not just declare a variable of type A or B in the agent, and then assign it to the correct agent? E.g., you could create in A the variable `employer` of type `B`, then say `myAgentA.employer = someAgentB`? Hope that helps! – Dylan Knowles Mar 24 '17 at 00:57
  • @SrijithBalakrishnan, I see this is one of your first questions on StackOverflow. Remember to mark this as an answer if it helped solve your problem. :) – Dylan Knowles Jun 15 '17 at 03:55