/* * * EDGECITY v1.5 -- Code of the Firms (the agents) * * 'Evolution of Central Places' a model by Paul Krugman * * This simulation is based on the demo model published by P. Krugman, which was * reformulated as an agent-based model by László Gulyás. * It was implemented in MAML v0.03 as an example application. * * (c) 1998, CEU Systems Laboratory * */ // Definition of a shorthand for 'model->NumOfPlaces' $define MAX : "model->NumOfPlaces"; @agent Firm { // The agent's internal variables @var: int loc; // Current location of the Firm @var: [] double diffs; // Array used to store probability // intervals when determining the move // End of create phase. This subroutine is automatically // called at the end of the creation of the agent. // It initializes the internal variables. @sub: (id) createEnd { @create [MAX] double diffs; // Creates the 'diffs' array. return self; // This method must always end by this. // (This originates in Obj-C & Swarm.) } // Initial setting of the firm's location @sub: (void) setLocation: (int) i { if ( (i>=0) && (iplaces[i]++; // If so, administrates it loc = i; } } // Moving from one location to another @sub: (void) move: (int) i { if ( (i>=0) && (iplaces[loc]--; // If so, administrates it model->places[i]++; loc = i; } } // Generates a totally random move (in case of noise) @sub: (void) randomMove { [self move: [uniformIntRand getIntegerWithMin: 0 withMax: MAX-1] ]; } // Determines the firms move @sub: (void) determineMove { double pot, avg, newPos, limit, dummy; // Local variables int i; // Variables: pot -- Market potential at the current location // avg -- Average market potential // newPos -- The point in the connected intervals which // determines the location to move to. // limit -- Temporary storage // dummy -- Temporary storage // i -- Loop variable // With the given probability it will be a random move if ( [uniformIntRand getIntegerWithMin: 0 withMax: 100] < model->randomMoveFactor ) [self randomMove]; else { // Otherwise it is a controlled move // Make the local copy of these values pot = [model->infoBank getPotential: loc]; avg = [model->infoBank getAverage]; // Calculates the probability limit by which the agent // would leave this location. limit = model->mobility*(avg-pot) * [model->infoBank getPercentage: loc]; // Draws a random number dummy = [uniformDblRand getDoubleWithMin: (double) 0 withMax: (double) 1.0 ]; // If the conditions hold it leaves the location if ((pot < avg) && (dummy < limit)) { // Build connected intervals representing to probabilities // by which the agent moves to locations. (Leave out those // with below-average market potential.) limit = (double)0.0; for (i=0; iinfoBank getPotential: i] - avg; if (diffs[i] > (double)0.0) { diffs[i] *= [model->infoBank getPercentage: i] * model->mobility; limit += diffs[i]; } } // Safety check, as getDoubleWithMin:withMax: does not like // min to be eaual to max if (limit > (double)0.0) { // Draw a random position in the intervals... newPos = [uniformDblRand getDoubleWithMin: (double)0.0 withMax: limit ]; // ... and determine the interval it is in. i = 0; limit = (double) 0.0; do { while ( (i