Example #1
0
        private float[] ComputeFriction(IZone[] zones, IDemographicCategoryGeneration cat, float[] friction)
        {
            var numberOfZones = zones.Length;

            float[] ret            = friction == null ? new float[numberOfZones * numberOfZones] : friction;
            var     rootModes      = this.Root.Modes;
            var     numberOfModes  = rootModes.Count;
            var     minFrictionInc = (float)Math.Exp(-10);

            // let it setup the modes so we can compute friction
            cat.InitializeDemographicCategory();
            try
            {
                Parallel.For(0, numberOfZones, new ParallelOptions()
                {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                }, delegate(int i)
                {
                    int index  = i * numberOfZones;
                    var origin = zones[i];
                    int vIndex = i * numberOfZones * numberOfModes;
                    for (int j = 0; j < numberOfZones; j++)
                    {
                        double c          = 0f;
                        var destination   = zones[j];
                        int feasibleModes = 0;
                        for (int mIndex = 0; mIndex < numberOfModes; mIndex++)
                        {
                            var mode = rootModes[mIndex];
                            if (!mode.Feasible(zones[i], zones[j], this.SimulationTime))
                            {
                                vIndex++;
                                continue;
                            }
                            var inc = mode.CalculateV(zones[i], zones[j], this.SimulationTime);
                            if (!(double.IsInfinity(inc) | double.IsNaN(inc)))
                            {
                                feasibleModes++;
                                c += inc >= 0 ? 1.0 : Math.Exp(inc);
                            }
                        }
                        if (feasibleModes == 0)
                        {
                            throw new XTMFRuntimeException("There was no valid mode to travel between " + zones[i].ZoneNumber + " and " + zones[j].ZoneNumber);
                        }
                        else
                        {
                            ret[index++] = (float)Math.Exp(this.ImpedianceParameter * Math.Log(c));
                        }
                    }
                });
            }
            catch (AggregateException e)
            {
                throw e.InnerException;
            }
            // Use the Log-Sum from the V's as the impedence function
            return(ret);
        }
Example #2
0
 private float[] ComputeFriction(IZone[] zones, IDemographicCategoryGeneration cat, float[] friction)
 {
     var numberOfZones = zones.Length;
     float[] ret = friction == null ? new float[numberOfZones * numberOfZones] : friction;
     var rootModes = this.Root.Modes;
     var numberOfModes = rootModes.Count;
     var minFrictionInc = (float)Math.Exp( -10 );
     // let it setup the modes so we can compute friction
     cat.InitializeDemographicCategory();
     try
     {
         Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int i)
         {
             int index = i * numberOfZones;
             var origin = zones[i];
             int vIndex = i * numberOfZones * numberOfModes;
             for ( int j = 0; j < numberOfZones; j++ )
             {
                 double c = 0f;
                 var destination = zones[j];
                 int feasibleModes = 0;
                 for ( int mIndex = 0; mIndex < numberOfModes; mIndex++ )
                 {
                     var mode = rootModes[mIndex];
                     if ( !mode.Feasible( zones[i], zones[j], this.SimulationTime ) )
                     {
                         vIndex++;
                         continue;
                     }
                     var inc = mode.CalculateV( zones[i], zones[j], this.SimulationTime );
                     if ( !( double.IsInfinity( inc ) | double.IsNaN( inc ) ) )
                     {
                         feasibleModes++;
                         c += inc >= 0 ? 1.0 : Math.Exp( inc );
                     }
                 }
                 if ( feasibleModes == 0 )
                 {
                     throw new XTMFRuntimeException( "There was no valid mode to travel between " + zones[i].ZoneNumber + " and " + zones[j].ZoneNumber );
                 }
                 else
                 {
                     ret[index++] = (float)Math.Exp( this.ImpedianceParameter * Math.Log( c ) );
                 }
             }
         } );
     }
     catch ( AggregateException e )
     {
         throw e.InnerException;
     }
     // Use the Log-Sum from the V's as the impedence function
     return ret;
 }
Example #3
0
        /// <summary>
        /// Assign workers to zones
        /// </summary>
        /// <param name="workplaceDistribution"></param>
        /// <param name="occupation"></param>
        private void AssignToWorkers(SparseTwinIndex<float> workplaceDistribution, IDemographicCategoryGeneration cat)
        {
            /*
             * -> For each zone
             * 1) Load the population
             * 2) Count the number of people
             * 3) Count the number of jobs for the zone
             * 4) Compute the ratio of people to jobs and Balance it by normalizing @ population level
             * 5) Shuffle the people to avoid bias
             * 6) Apply the random split algorithm from the Population Synthesis to finish it off
             */
            var zoneIndexes = this.ZoneArray.ValidIndexies().ToArray();
            var flatZones = this.ZoneArray.GetFlatData();
            var numberOfZones = zoneIndexes.Length;
            var flatWorkplaceDistribution = workplaceDistribution.GetFlatData();
            var flatPopulation = this.Root.Population.Population.GetFlatData();
            try
            {
                Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount },
                    delegate()
                    {
                        return new Assignment() { dist = this.ZoneArray.CreateSimilarArray<float>(), indexes = null };
                    },
                delegate(int z, ParallelLoopState unused, Assignment assign)
                {
                    var dist = assign.dist;
                    var indexes = assign.indexes;
                    var flatDist = dist.GetFlatData();
                    var distributionForZone = flatWorkplaceDistribution[z];
                    Random rand = new Random( ( this.RandomSeed * z ) * ( this.CurrentOccupationIndex * numberOfZones ) );
                    IZone zoneI = flatZones[z];
                    var zonePop = flatPopulation[z];
                    int popLength = zonePop.Length;
                    if ( indexes == null || indexes.Length < popLength )
                    {
                        indexes = new int[(int)( popLength * 1.5 )];
                        assign.indexes = indexes;
                    }

                    int totalPeopleInCat = 0;
                    // 1+2) learn who is qualified for this distribution
                    for ( int i = 0; i < popLength; i++ )
                    {
                        var person = zonePop[i];
                        if ( cat.IsContained( person ) )
                        {
                            indexes[totalPeopleInCat] = i;
                            totalPeopleInCat++;
                        }
                    }
                    // 3) Count how many jobs are expected to come from this zone
                    double totalJobsFromThisOrigin = 0;
                    for ( int i = 0; i < numberOfZones; i++ )
                    {
                        totalJobsFromThisOrigin += ( flatDist[i] = distributionForZone[i] );
                    }
                    if ( totalJobsFromThisOrigin == 0 )
                    {
                        return assign;
                    }
                    // 4) Calculate the ratio of people who work to the number of jobs so we can balance it again
                    float normalizationFactor = 1 / (float)totalJobsFromThisOrigin;
                    for ( int i = 0; i < numberOfZones; i++ )
                    {
                        flatDist[i] = flatDist[i] * normalizationFactor;
                    }

                    // 5) card sort algo
                    for ( int i = totalPeopleInCat - 1; i > 0; i-- )
                    {
                        var swapIndex = rand.Next( i );
                        var temp = indexes[i];
                        indexes[i] = indexes[swapIndex];
                        indexes[swapIndex] = temp;
                    }
                    // 6) Apply the random split algorithm from the Population Synthesis to finish it off
                    var flatResult = this.SplitAndClear( totalPeopleInCat, dist, rand );
                    int offset = 0;
                    for ( int i = 0; i < numberOfZones; i++ )
                    {
                        var ammount = flatResult[i];
                        for ( int j = 0; j < ammount; j++ )
                        {
                            if ( offset + j >= indexes.Length ||
                                indexes[offset + j] > zonePop.Length )
                            {
                                throw new XTMFRuntimeException( "We tried to assign to a person that does not exist!" );
                            }
                            zonePop[indexes[offset + j]].WorkZone = flatZones[i];
                        }
                        offset += ammount;
                    }
                    return assign;
                }, delegate(Assignment unused) { } );
            }
            catch ( AggregateException e )
            {
                throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
            }
        }
Example #4
0
        /// <summary>
        /// Assign workers to zones
        /// </summary>
        /// <param name="workplaceDistribution"></param>
        /// <param name="category"></param>
        private void AssignToWorkers(SparseTwinIndex <float> workplaceDistribution, IDemographicCategoryGeneration category)
        {
            /*
             * -> For each zone
             * 1) Load the population
             * 2) Count the number of people
             * 3) Count the number of jobs for the zone
             * 4) Compute the ratio of people to jobs and Balance it by normalizing @ population level
             * 5) Shuffle the people to avoid bias
             * 6) Apply the random split algorithm from the Population Synthesis to finish it off
             */
            var zoneIndexes               = ZoneArray.ValidIndexies().ToArray();
            var flatZones                 = ZoneArray.GetFlatData();
            var numberOfZones             = zoneIndexes.Length;
            var flatWorkplaceDistribution = workplaceDistribution.GetFlatData();
            var flatPopulation            = Root.Population.Population.GetFlatData();

            Parallel.For(0, numberOfZones, new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            },
                         delegate
            {
                return(new Assignment {
                    Dist = ZoneArray.CreateSimilarArray <float>(), Indexes = null
                });
            },
                         delegate(int z, ParallelLoopState unused, Assignment assign)
            {
                var dist                = assign.Dist;
                var indexes             = assign.Indexes;
                var flatDist            = dist.GetFlatData();
                var distributionForZone = flatWorkplaceDistribution[z];
                Random rand             = new Random((RandomSeed * z) * (CurrentOccupationIndex * numberOfZones));
                var zonePop             = flatPopulation[z];
                int popLength           = zonePop.Length;
                if (indexes == null || indexes.Length < popLength)
                {
                    indexes        = new int[(int)(popLength * 1.5)];
                    assign.Indexes = indexes;
                }

                int totalPeopleInCat = 0;
                // 1+2) learn who is qualified for this distribution
                for (int i = 0; i < popLength; i++)
                {
                    var person = zonePop[i];
                    if (category.IsContained(person))
                    {
                        indexes[totalPeopleInCat] = i;
                        totalPeopleInCat++;
                    }
                }
                // 3) Count how many jobs are expected to come from this zone
                double totalJobsFromThisOrigin = 0;
                for (int i = 0; i < numberOfZones; i++)
                {
                    totalJobsFromThisOrigin += (flatDist[i] = distributionForZone[i]);
                }
                if (totalJobsFromThisOrigin == 0)
                {
                    return(assign);
                }
                // 4) Calculate the ratio of people who work to the number of jobs so we can balance it again
                float normalizationFactor = 1 / (float)totalJobsFromThisOrigin;
                for (int i = 0; i < numberOfZones; i++)
                {
                    flatDist[i] = flatDist[i] * normalizationFactor;
                }

                // 5) card sort algo
                for (int i = totalPeopleInCat - 1; i > 0; i--)
                {
                    var swapIndex      = rand.Next(i);
                    var temp           = indexes[i];
                    indexes[i]         = indexes[swapIndex];
                    indexes[swapIndex] = temp;
                }
                // 6) Apply the random split algorithm from the Population Synthesis to finish it off
                var flatResult = SplitAndClear(totalPeopleInCat, dist, rand);
                int offset     = 0;
                for (int i = 0; i < numberOfZones; i++)
                {
                    var ammount = flatResult[i];
                    for (int j = 0; j < ammount; j++)
                    {
                        if (offset + j >= indexes.Length ||
                            indexes[offset + j] > zonePop.Length)
                        {
                            throw new XTMFRuntimeException(this, "We tried to assign to a person that does not exist!");
                        }
                        zonePop[indexes[offset + j]].WorkZone = flatZones[i];
                    }
                    offset += ammount;
                }
                return(assign);
            }, delegate { });
        }