예제 #1
0
        private float[] ComputeFriction(IZone[] zones, IDemographicCategory[][] cats, float[][][] productionSet, float[] friction, float[] production, int subsetIndex)
        {
            var numberOfZones = zones.Length;

            float[] ret = friction ?? (new float[numberOfZones * numberOfZones]);
            if (!String.IsNullOrWhiteSpace(LoadFrictionFileName))
            {
                LoadFriction(ret);
            }
            else
            {
                ComputeFriction(zones, numberOfZones, ret);
            }
            InteractiveModeSplit.StartNewInteractiveModeSplit(TotalBlendSets);
            SumProduction(production, productionSet, subsetIndex);
            try
            {
                float[] ratio = new float[cats[subsetIndex].Length];
                var     mpd   = Root.ModeParameterDatabase;
                for (int i = 0; i < numberOfZones; i++)
                {
                    // let it setup the modes so we can compute friction
                    ProcessRatio(i, ratio, production, productionSet[subsetIndex]);
                    SetupModeChoiceParameters(cats[subsetIndex], ratio, mpd);
                    SaveModeChoice(zones, numberOfZones, i);
                }
            }
            catch (AggregateException e)
            {
                if (e.InnerException != null)
                {
                    throw e.InnerException;
                }
            }
            // Use the Log-Sum from the V's as the impedance function
            if (!String.IsNullOrWhiteSpace(SaveFrictionFileName))
            {
                SaveFriction(ret);
            }
            return(ret);
        }
        private void ComputeFriction(IZone[] zones, IDemographicCategory[][] cats, float[][][] productions, float[][][] attractions, float[][] friction, float[] production, float[] attraction)
        {
            var  numberOfZones  = zones.Length;
            bool loadedFriction = false;

            if (!String.IsNullOrWhiteSpace(LoadFrictionFileName))
            {
                LoadFriction(friction, -1);
                loadedFriction = true;
            }
            else
            {
                ClearFriction(friction, numberOfZones);
            }

            var mpd = Root.ModeParameterDatabase;

            float[] subsetRatios = new float[productions.Length];
            SumProductionAndAttraction(production, attraction, productions, attractions);
            for (int subset = 0; subset < cats.Length; subset++)
            {
                InteractiveModeSplit.StartNewInteractiveModeSplit(MultiBlendSets.Count);
                float[] ratio = new float[cats[subset].Length];
                for (int i = 0; i < numberOfZones; i++)
                {
                    ComputeSubsetRatios(i, subsetRatios, productions);
                    ProcessBlendsetRatio(i, ratio, productions[subset]);
                    // if there is no production for this origin we can just skip ahead for the next zone
                    if (production[i] == 0)
                    {
                        continue;
                    }
                    // if there is something here to process
                    SetupModeChoice(cats, ratio, mpd, subset);
                    GatherUtilities(zones, friction, attraction, numberOfZones, loadedFriction, subsetRatios, subset, i);
                }
                InteractiveModeSplit.EndInterativeModeSplit();
            }
            ConvertToFriction(friction, zones);
            CheckSaveFriction(friction);
        }
예제 #3
0
        private void UpdateData(float[][] flatRet, float[] flatProd, IDemographicCategory[][] cats, float[][][] productions, float[][][] attractions, IZone[] zones, int subset, bool loadedFriction)
        {
            var numberOfZones = flatProd.Length;

            InteractiveModeSplit.StartNewInteractiveModeSplit(TotalBlendSets);
            var mpd = Root.ModeParameterDatabase;

            float[] subsetRatios = new float[productions.Length];
            float[] ratio        = new float[cats[subset].Length];
            for (int i = 0; i < numberOfZones; i++)
            {
                var   p = flatProd[i];
                float factor;
                if (p == 0)
                {
                    // if there is no production, clear out everything
                    for (int j = 0; j < numberOfZones; j++)
                    {
                        flatRet[i][j] = 0f;
                    }
                    continue;
                }
                if (UseProductionPercentages)
                {
                    var totalProduction = 0f;
                    factor = 0f;
                    for (int j = 0; j < attractions[subset].Length; j++)
                    {
                        totalProduction += productions[subset][j][i];
                    }
                    if (totalProduction <= 0)
                    {
                        for (int j = 0; j < numberOfZones; j++)
                        {
                            flatRet[i][j] = 0f;
                        }
                        continue;
                    }
                    // compute how much each one contributes to the total
                    // then sum it all up into our final factor
                    for (int j = 0; j < productions[subset].Length; j++)
                    {
                        ratio[j] = productions[subset][j][i] / totalProduction;
                        factor  += productions[subset][j][i];
                    }
                    float retTotal = 0;
                    for (int j = 0; j < flatRet[i].Length; j++)
                    {
                        retTotal += flatRet[i][j];
                    }
                    factor = factor / retTotal;
                    // in this case we use the attraction since that is where the people
                    // are actually stored in this case
                    ComputeSubsetRatios(i, subsetRatios, attractions);
                    if (factor <= 0f)
                    {
                        for (int j = 0; j < numberOfZones; j++)
                        {
                            flatRet[i][j] = 0f;
                        }
                        continue;
                    }
                    // we actually still need to operate on the friction since it will be in totals
                    loadedFriction = false;
                }
                else
                {
                    var sum    = 0f;
                    var retRow = flatRet[i];
                    // Gather the sum of all of the destinations from this origin
                    for (int j = 0; j < numberOfZones; j++)
                    {
                        sum += retRow[j];
                    }
                    // The rows should already be seeded however, if they are not
                    // just return since all of the values are zero anyway
                    if (sum <= 0)
                    {
                        throw new XTMFRuntimeException(this, "In '" + Name + "' there was no attraction for zone " + zones[i].ZoneNumber);
                    }
                    ProcessRatio(i, ratio, flatProd, productions[subset]);
                    ComputeSubsetRatios(i, subsetRatios, productions);
                    // p is already the production of this subset
                    factor = p / sum;
                }
                SetupModeSplit(cats, subset, mpd, ratio);
                // make sure to only include the total factor of people that belong to this subset
                // now that we have the new factor we update the demand
                UpdateDemand(flatRet, zones, numberOfZones, loadedFriction, i, factor);
            }
            if (Transpose)
            {
                TransposeMatrix(flatRet);
            }
            if (!String.IsNullOrWhiteSpace(SaveFrictionFileName))
            {
                SaveFriction(flatRet);
            }
        }
예제 #4
0
        private void DistributePopulation(DemographicCategoryGeneration cat, float[] ageProbability, float[][] assignedPersons, int catIndex, float[][] ret)
        {
            var timeOfDayRate         = CurrentTimeOfDayRates.GiveData();
            var dailyRates            = CurrentDailyRates.GiveData();
            var zones                 = Root.ZoneSystem.ZoneArray.GetFlatData();
            var numberOfMobilityTypes = GetMobilityTypeTotal();
            var currentMobilityType   = catIndex % numberOfMobilityTypes;

            ModeSplit.StartNewInteractiveModeSplit(NumberOfGenerations);
            // Setup the mode choice function, since each zone is the same, we only need to do this once
            cat.InitializeDemographicCategory();
            var age = cat.AgeCategoryRange[0].Start;
            //ageOfffset = foreach each OD Pair, for each mobility category multiplied by the age - 2 (workrs start at 2).
            var ageOffset = (5 * zones.Length * zones.Length) * (age - 2);

            // for each origin zone
            Parallel.For(0, zones.Length, i =>
            {
                var pdI = zones[i].PlanningDistrict;
                // Offset of the origin
                var iOffset = i * zones.Length * numberOfMobilityTypes;
                // offset by the age category plus the mobility category offset
                iOffset += ageOffset + currentMobilityType * zones.Length;
                // for each destination
                var row = ret[i];
                var assignedPersonRow = assignedPersons[i];
                if (ageProbability[i] == 0)
                {
                    for (int j = 0; j < zones.Length; j++)
                    {
                        row[j] = 0;
                    }
                }
                else
                {
                    int currentJIndex = 0;
                    for (int j = 0; j < zones.Length; j++)
                    {
                        if (assignedPersonRow[j] <= 0)
                        {
                            row[j] = 0;
                        }
                        else if (j == i)
                        {
                            throw new XTMFRuntimeException(this, "We found assigned persons for an intra-zonal work trip!");
                        }
                        else
                        {
                            var pdJ = zones[j].PlanningDistrict;
                            // compute the mode choice
                            var util = ModeSplit.ComputeUtility(zones[i], zones[j]);
                            if (float.IsNaN(util) | float.IsInfinity(util))
                            {
                                throw new XTMFRuntimeException(this, "We came across an invalid utility! Age = " + age + " origin = " + zones[i].ZoneNumber + " destination = " + zones[j].ZoneNumber
                                                               + " demographic category = '" + cat.ToString() + "'");
                            }
                            // Process how many persons go here
                            // probabilities contains the probability of being in that age category already
                            var rate    = timeOfDayRate[pdI, pdJ, age] * dailyRates[pdI, pdJ, age];
                            var persons = ageProbability[i] * assignedPersonRow[j];
                            if ((rate == 0) & (persons > 0))
                            {
                                throw new XTMFRuntimeException(this, "We lost generation for " + zones[i].ZoneNumber + " to " + zones[j].ZoneNumber + ". " + persons
                                                               + " persons in category " + catIndex + ".");
                            }
                            row[j] = persons * rate * MobilityCache[iOffset + currentJIndex];
                        }
                        currentJIndex++;
                    }
                }
            });
        }