Exemplo n.º 1
0
 public void TestSimpleGravityModelSolution()
 {
     var data = CreateData();
     var gm = new GravityModel( data, null, 0.0f, 300 );
     var o = SparseArray<float>.CreateSparseArray( new int[] { 1, 2 }, new float[] { 2, 2 } );
     var d = SparseArray<float>.CreateSparseArray( new int[] { 1, 2 }, new float[] { 1.5f, 2.5f } );
     var ret = gm.ProcessFlow( o, d, new int[] { 1, 2 } );
     var result = ret.GetFlatData();
     Assert.AreEqual( 0.5f, result[0][0], 0.0001f );
     Assert.AreEqual( 1.5f, result[0][1], 0.0001f);
     Assert.AreEqual( 1f, result[1][0], 0.0001f);
     Assert.AreEqual( 1f, result[1][1], 0.0001f);
 }
Exemplo n.º 2
0
        private void InitializeFlows()
        {
            this.Progress = 0;
            // we are going to need to split based on this information
            this.ZoneArray = this.Root.ZoneSystem.ZoneArray;
            var occupations = this.Root.Demographics.OccupationCategories;
            var validZones = this.ZoneArray.ValidIndexies().ToArray();
            var numberOfZones = validZones.Length;
            //[Occupation][O , D]
            var distribution = occupations.CreateSimilarArray<SparseTwinIndex<float>>();
            //Generate the place of work place of residence OD's
            SparseArray<float> O = this.ZoneArray.CreateSimilarArray<float>();
            SparseArray<float> D = this.ZoneArray.CreateSimilarArray<float>();
            var occupationIndexes = occupations.ValidIndexies().ToArray();
            var numCat = Categories.Count;
            // Start burning that CPU
            Thread.CurrentThread.Priority = ThreadPriority.Highest;
            SparseTwinIndex<float> workplaceDistribution = null;
            SparseTwinIndex<float> prevWorkplaceDistribution = null;
            float[] friction = null;
            float[] nextFriction = null;
            MultiRunGPUGravityModel multiRunGPU = null;
            for ( int i = 0; i < numCat; i++ )
            {
                this.CurrentOccupationIndex = i;
                Task assignToPopulation = null;
                if ( i > 0 )
                {
                    assignToPopulation = new Task( delegate()
                        {
                            if ( prevWorkplaceDistribution != null )
                            {
                                // We actually are assigning to the previous category with this data so we need i - 1
                                AssignToWorkers( prevWorkplaceDistribution, this.Categories[i - 1] );
                                prevWorkplaceDistribution = null;
                            }
                        } );
                    assignToPopulation.Start();
                }
                Task computeNextFriction = null;
                if ( i + 1 < numCat )
                {
                    computeNextFriction = new Task( delegate()
                    {
                        nextFriction = this.ComputeFriction( ZoneArray.GetFlatData(), this.Categories[i + 1], nextFriction );
                    } );
                    computeNextFriction.Start();
                }

                this.Categories[i].Generate( O, D );
                if ( this.UseGPU )
                {
                    if ( i == 0 )
                    {
                        try
                        {
                            Parallel.Invoke( () => friction = this.ComputeFriction( ZoneArray.GetFlatData(), this.Categories[i], friction ),
                            () => multiRunGPU = new MultiRunGPUGravityModel( O.GetFlatData().Length, ( progress => this.Progress = ( progress / numCat ) + ( (float)i / numCat ) ), this.Epsilon, this.MaxIterations ) );
                        }
                        catch ( AggregateException e )
                        {
                            throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
                        }
                    }
                    workplaceDistribution = multiRunGPU.ProcessFlow( friction, O, D );
                }
                else
                {
                    GravityModel gravityModel = new GravityModel( ImpedenceFunction, ( progress => this.Progress = ( progress / numCat ) + ( (float)i / numCat ) ), this.Epsilon, this.MaxIterations );
                    workplaceDistribution = gravityModel.ProcessFlow( O, D, validZones );
                }
                this.Progress = ( (float)( i + 1 ) / numCat );
                if ( assignToPopulation != null )
                {
                    try
                    {
                        assignToPopulation.Wait();
                        assignToPopulation.Dispose();
                        assignToPopulation = null;
                    }
                    catch ( AggregateException e )
                    {
                        throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
                    }
                }
                if ( computeNextFriction != null )
                {
                    try
                    {
                        computeNextFriction.Wait();
                        computeNextFriction.Dispose();
                        computeNextFriction = null;
                    }
                    catch ( AggregateException e )
                    {
                        throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
                    }
                }
                prevWorkplaceDistribution = workplaceDistribution;
                var frictionTemp = friction;
                friction = nextFriction;
                nextFriction = friction;
            }
            friction = null;
            nextFriction = null;
            prevWorkplaceDistribution = null;
            if ( multiRunGPU != null )
            {
                multiRunGPU.Dispose();
                multiRunGPU = null;
            }
            AssignToWorkers( workplaceDistribution, this.Categories[numCat - 1] );
            workplaceDistribution = null;
            // ok now we can relax
            Thread.CurrentThread.Priority = ThreadPriority.Normal;
            GC.Collect();
        }