Code Monkey home page Code Monkey logo

Comments (3)

mrerrormessage avatar mrerrormessage commented on June 4, 2024

I think we can be cleverer on ArrayAgentSet, if it is acceptable to mutate the array. The general strategy would be something like what follows.

def selectRandom(a: Array[Agent], n: Int = 0): Option[Agent] = {
  if (a.isEmpty || n >= a.length)
    None
  else {
    val i = Random.nextInt(a.length - n) + n
    val agent = a(i)
    if (agent.isAlive)
      Some(Agent)
    else {
      a(i) = a(n)
      a(n) = agent
      selectRandom(a, n + 1)
    }
  }
}

As I understand the time-complexity of get/update, this would be O(1) in the best case and only O(n) in the worst-case, which is what we have now anyway.

from netlogo.

elfprince13 avatar elfprince13 commented on June 4, 2024

If it were possible for AgentSets to subscribe to "death events" for contained agents, this would be a lot easier to do efficiently in both cases.

from netlogo.

qiemem avatar qiemem commented on June 4, 2024

You can actually do something quite similar to @mrerrormessage's solution without modifying the array. Instead, you can use a map to track which elements have been eliminated and redirect to those still in the candidate pool. As a bonus, this can operate on any Seq-like data structure, not just arrays. Note that these methods also generalize to n-of to make that O(sample size)-ish. Here's a generalized solution I came up with:

def sample[T: Manifest](s: Seq[T], sampleSize: Int, pred: T => Boolean = (x: T) => true): Seq[T] = {
    val m = new mutable.OpenHashMap[Int, T](s.size)
    val res = new Array[T](sampleSize)
    var insertIndex = 0
    var startIndex = 0
    while (insertIndex < sampleSize) {
        val i = Random.nextInt(s.size - startIndex) + startIndex
        val x: T = m.put(i, s(startIndex)).getOrElse(s(i))
        if (pred(x)) {
            res(insertIndex) = x: T
            insertIndex += 1
        }
        startIndex+=1
    }
    res
}

However, note that the constant factor on the hashmap lookup does hurt the performance of this. I compared it to @mrerrormessage's solution, but cloning the array at the beginning. Under 500 elements, the array version still beats the map version, especially if a decent percent of the agents are dead. Above that, the map version wins, unless the sample size is largish or there are a lot of dead agents. I tried various types of maps (OpenHashMap performed by far the best) and with size hints (though they didn't help).

I also tried doing this with immutable Vectors, since their pretty perfect for this situation (constant time read and write, persistent), but the map version beat it by a lot.

I tested a couple other solutions too, but nothing worth mentioning. Main takeaway: hot damn, cloning arrays is fast.

A hybrid solution that clones the array when the agentset is small and uses a map when big could be nice, but is perhaps is unnecessarily complicated.

from netlogo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.