File

src/app/demand/demand.service.ts

Description

Estimates the O/D matrix of the traffic demand.

Index

Properties
Methods

Constructor

constructor(network: NetworkService)
Parameters :
Name Type Optional
network NetworkService No

Methods

Private argmin
argmin(linkFlows: LinkFlow[], odMatrixAssignment: number[][])

Argument of the minimum function.

Parameters :
Name Type Optional Description
linkFlows LinkFlow[] No

The link flows

odMatrixAssignment number[][] No

Assignment matrix of the O/D pair

Returns : number
Public calcOdMatrix
calcOdMatrix()

Calculates O/D matrix.

Returns : Observable<any>
Public changeDemand
changeDemand(demand: number[])
Parameters :
Name Type Optional
demand number[] No
Returns : void
Public changeStartingTimes
changeStartingTimes(startingTimes: number[])
Parameters :
Name Type Optional
startingTimes number[] No
Returns : void
Private estimate
estimate(linkFlows: LinkFlow[], odMatrixAssignment: number[][], x: number)

Estimates the sum for the unknown demand.

Parameters :
Name Type Optional Description
linkFlows LinkFlow[] No

The link flows

odMatrixAssignment number[][] No

Assignment matrix of the O/D pair

x number No

The unknown demand

Returns : number
Public getOdMatrix
getOdMatrix()
Returns : number[]
Public getStartingTimes
getStartingTimes()
Returns : number[]
Public gls
gls(linkFlows: LinkFlow[], assignmentMatrix: [][][])

Generalized Least Squares (GLS).

Parameters :
Name Type Optional Description
linkFlows LinkFlow[] No

The link flows

assignmentMatrix [][][] No

Assignment matrix [pairs,paths,edges]

Returns : number[]

The array of the demand

Private isOnPath
isOnPath(odMatrixAssignment: number[][], i: number)

Checks that the edge belongs to one of the paths of the O/D pair.

Parameters :
Name Type Optional Description
odMatrixAssignment number[][] No

Assignment matrix of the O/D pair

i number No

The index of the edge

Returns : boolean
Public reset
reset()
Returns : void
Private sum
sum(odMatrixAssignment: number[][], i: number, x: number)

Sums the unknown demand probability for each path.

Parameters :
Name Type Optional Description
odMatrixAssignment number[][] No

Assignment matrix of the O/D pair

i number No

The index of the edge

x number No

The unknown demand

Returns : number

Properties

Private odMatrix
odMatrix: number[]
Type : number[]
Default value : []

The array of the demand.

Private startingTimes
startingTimes: number[]
Type : number[]
Default value : []

Starting time in seconds for each O/D pair.

import { Injectable } from '@angular/core';
import { Observable, of } from 'rxjs';

import { NetworkService } from '../network/network.service';
import { LinkFlow } from '../network/graph';
import { round } from '../utils';
import { uiConfig } from '../ui/ui-config';

/**
 * Estimates the O/D matrix of the traffic demand.
 */
@Injectable() export class DemandService {

    /**
     * The array of the demand.
     */
    private odMatrix: number[] = [];

    /**
     * Starting time in seconds for each O/D pair.
     */
    private startingTimes: number[] = [];

    constructor(private network: NetworkService) { }

    public reset(): void {
        this.odMatrix = [];
    }

    /**
     * Calculates O/D matrix.
     */
    public calcOdMatrix(): Observable<any> {
        // Gets link flows from network.
        const linkFlows = this.network.getLinkFlows();
        // Gets assignment matrix from network.
        const assignmentMatrix = this.network.getAssignmentMatrix();
        // Calculates demand.
        this.odMatrix = this.gls(linkFlows, assignmentMatrix);
        // Initializes starting times.
        this.startingTimes = Array(this.odMatrix.length).fill(0);
        return of(null);
    }

    public getOdMatrix(): number[] {
        return this.odMatrix;
    }

    public changeDemand(demand: number[]): void {
        if (demand.length > 0) {
            this.odMatrix = demand;
        }
    }

    public getStartingTimes(): number[] {
        return this.startingTimes;
    }

    public changeStartingTimes(startingTimes: number[]): void {
        if (startingTimes.length > 0) {
            this.startingTimes = startingTimes;
        }
    }

    /**
     * Generalized Least Squares (GLS).
     * @param linkFlows The link flows
     * @param assignmentMatrix Assignment matrix [pairs,paths,edges]
     * @returns The array of the demand
     */
    public gls(linkFlows: LinkFlow[], assignmentMatrix: number[][][]): number[] {
        const demand: number[] = [];
        // Calculates argument of the minimum for each O/D pair.
        for (let z = 0; z < assignmentMatrix.length; z++) {
            demand[z] = assignmentMatrix[z].length > 0 ? this.argmin(linkFlows, assignmentMatrix[z]) : null;
        }
        return demand;
    }

    /**
     * Argument of the minimum function.
     * @param linkFlows The link flows
     * @param odMatrixAssignment Assignment matrix of the O/D pair
     */
    private argmin(linkFlows: LinkFlow[], odMatrixAssignment: number[][]): number {
        const estimations: number[] = [];
        // The unknown demand.
        let x = 0;
        estimations[x] = this.estimate(linkFlows, odMatrixAssignment, x);
        if (estimations[x] == 0) { return 0; }
        do {
            x++;
            estimations[x] = this.estimate(linkFlows, odMatrixAssignment, x);
        } while (estimations[x] <= estimations[x - 1] && x <= uiConfig.maxDemand);
        return x - 1;
    }

    /**
     * Estimates the sum for the unknown demand.
     * @param linkFlows The link flows
     * @param odMatrixAssignment Assignment matrix of the O/D pair
     * @param x The unknown demand
     */
    private estimate(linkFlows: LinkFlow[], odMatrixAssignment: number[][], x: number): number {
        let sum = 0;
        for (let i = 0; i < linkFlows.length; i++) {
            if (linkFlows[i].value > 0 && this.isOnPath(odMatrixAssignment, i)) {
                const base = linkFlows[i].value - this.sum(odMatrixAssignment, i, x);
                sum += Math.pow(base, 2) / linkFlows[i].variance;
            }
        }
        return round(sum, 2);
    }

    /**
     * Sums the unknown demand probability for each path.
     * @param odMatrixAssignment Assignment matrix of the O/D pair
     * @param i The index of the edge
     * @param x The unknown demand
     */
    private sum(odMatrixAssignment: number[][], i: number, x: number): number {
        let sum = 0;
        for (let n = 0; n < odMatrixAssignment.length; n++) {
            if (odMatrixAssignment[n][i] > 0) {
                sum += odMatrixAssignment[n][i] * x;
            }
        }
        return round(sum, 2);
    }

    /**
     * Checks that the edge belongs to one of the paths of the O/D pair.
     * @param odMatrixAssignment Assignment matrix of the O/D pair
     * @param i The index of the edge
     */
    private isOnPath(odMatrixAssignment: number[][], i: number): boolean {
        for (let n = 0; n < odMatrixAssignment.length; n++) {
            if (odMatrixAssignment[n][i] > 0) {
                return true;
            }
        }
        return false;
    }

}

result-matching ""

    No results matching ""