! Find either user equilibrium, or system/social optimum for traffic
flow problem in a congested network. The time to transit
a link in the network is an increasing function of the
traffic on the link. At a user equilibrium, each user
chooses the shortest path from his origin to his destination.
The total travel time under the user equilibrium is
typically greater than the system optimum. Under a system
optimum, total delay time is minimized;
! Because of complementarity constraints, we should
turn on the Global Solver option by clicking on:
LINGO | Options | Global Solver | Use Global Solver
;
! Keywords: Braess Paradox, Complementarity constraint, Congestion,
Consumer Choice, Equilibrium, Network, System optimum,
Traffic Equilibrium, User Equilibrium;
SETS:
Node; ! Nodes of the network;
Link( Node, Node): Bcost, Cap, TotFlo, ! Links of network;
ArcTime;
Trip( Node, Node): Dem; ! Trips to be routed in network;
Dest( Node) | @sum( Node(n): @IN( Trip, n, &1)); !Destination nodes;
Link4Dest( Link, Dest): X, Slk; ! (from, to, by destination) flow;
NXD( Node, Dest): R; ! Intermediate nodes to terminal nodes;
SYS /1..1/; ! Utility set, size 1, convenieht for conditional constraints;
ENDSETS
! Parameters:
Dem(j,t) = flow that starts at j and wants to go to t,
Bcost(i,j) = travel cost(or delay, or travel time) from i to j when there is
no congestion,
Cap(i,j) = flow level from i to j at which congestion or
delay doubles, (and gets larger really fast).
UserOpt = 1 if we want User optimum/equilibrium, i.e., each
user chooses shortest path available, or
= 0 if we want System/social optimum, i.e., we direct
traffic so total delay is minimized.
Power = exponent for the flow which determines how travel
time increases with flow. 4 is a typical value used;
! Variables:
X(i,j,t) = flow from node i to j destined for t,
TotFlow(i,j) = total flow from i to j,
ArcTime(i,j) = congestion cost/delay from i to j,
R(i,t) = Remaining delay at i to get to destination t
by cheapest/fastest route,
Slk(i,j,t) = Difference in cost of going from i to j
to get to t, vs. going by the cheapest
route from i to destination t,
= ArcTime(i,j)+R(j,t) - R(i,t),
;
DATA:
! Braess data set. The network is
C
/ ^ \
/ | \
A | D
\ | /
\ | /
B
!CBraess; UserOpt = 1!CBraess; Scale = 1!CBraess; Power = 1!CBraess; Style = 1!CBraess; Node = A B C D
! From_node, To_node, Base/no_traffic cost, Capacity;
!CBraess; Link BCost Cap =
A B 0 10
A C 50 1
B C 10 1
B D 50 1
C D 0 10
;
! Trip data: origin, destination, trips;
!CBraess; Trip Dem =
A D 6
;
! Data set 2;
! Choose either User optimum (1), or system/social optimum(0);
!Ctraflo2 UserOpt = 1;
!Ctraflo2 Scale = 1; !Ctraflo2 Node = A B C D E; !Ctraflo2 Power = 4; !Ctraflo2 Style = 0; Bcost(i,j)*(1 + Scale*( TotFlo(i,j)/Cap(i,j))^ Power);
! Trips people want to make and number
per minute wishing to make the trips;
! Ctraflo2
Trip Dem =
A D 60
E C 5;
! Links of network and congestion parameters;
!Ctraflo2
Link BCost Cap =
A B 25.3714 45.9034
A C 51.7539 76.1578
B C 11.7538 52.5742
B D 51.7539 76.1578
C D 25.3714 45.9034
E A 11.7539 52.5743
E B 51.7539 76.1577;
! This data set can illustrate the Braess Paradox if
we set the demand from E to C = 0.
First, solve for the resulting user equilibrium(Useropt=1),
Next, make link B to C really unattractive by
setting BCost for B to C = 9999999.
Finally, solve again and notice that this removal of an
arc from the network made everyone's travel
time or cost lower;
! Case Sious Falls. This is a subset of the Sioux Falls data set;
! Network structure:
1--------------------2
| |
3------4------5------6
| | | |
| | 9------8------7
| | | | |
12-----11-----10-----16-----18
| | | \ | |
| | | \ | |
| | | 17 /
| | | | /
| 14-----15-----19 /
| | | | /
| 23-----22 | /
| | | \ | /
| | | \ |/
13-----24-----21-----20
;
!CSioux UserOpt = 0; !CSioux Scale = .03; !CSioux Power = 4; !CSioux Style = 0; Bcost(i,j)*(1 + Scale*( TotFlo(i,j)/Cap(i,j))^ Power);
!CSioux Node = 1..10;
! From_node, To_node, Base/no_traffic cost, Capacity;
!CSioux Link BCost Cap =
1 2 6.0008 25900.20
2 1 6.0008 25900.20 ! Add node 2 to network;
!CSioux 3 1 1.0000 23403.47 !CSioux 1 3 1.0000 23403.47
3 4 4.0000 17110.52 ! Add 4;
!CSioux 4 3 4.0000 17110.52
4 5 2.0000 17782.79 ! Add 5;
!CSioux 5 4 2.0000 17782.79
2 6 5.0000 4958.18 ! 6;
!CSioux 6 2 5.0000 4958.18
5 6 4.0000 4948.00
6 5 4.0000 4948.00
6 8 2.0000 4898.59 ! 8;
!CSioux 8 6 2.0000 4898.59
8 7 3.0000 7841.81 ! 7;
!CSioux 7 8 3.0000 7841.81
9 8 10.0000 5050.19 ! 9;
!CSioux 8 9 10.0000 5050.19
5 9 5.0000 10000.00
9 5 5.0000 10000.00
9 10 3.0000 13915.79 ! 10;
!CSioux 10 9 3.0000 13915.79;
! Trip data: origin, destination, trips;
!CSioux Trip Dem =
1 2 100 ! Add node 2;
!CSioux 2 1 100
1 3 100 ! Add node 3;
!CSioux 3 1 100
2 3 100
3 2 100
1 4 500 ! Add node 4;
!CSioux 4 1 500
2 4 200
4 2 200
3 4 200
4 3 200
1 5 200 ! Node 5;
!CSioux 5 1 200
2 5 100
5 2 100
3 5 100
5 3 100
4 5 500
5 4 500
1 6 300 ! Node 6;
!CSioux 6 1 300
2 6 400
6 2 400
3 6 300
6 3 300
4 6 400
6 4 400
5 6 200
6 5 200
1 8 800 ! 8;
!CSioux 8 1 800
2 8 400
8 2 400
3 8 200
8 3 200
4 8 700
8 4 700
5 8 500
8 5 500
6 8 800
8 6 800
1 7 500 ! 7;
!CSioux 7 1 500
2 7 200
7 2 200
3 7 100
7 3 100
4 7 400
7 4 400
5 7 200
7 5 200
6 7 400
7 6 400
8 7 1000
7 8 1000
1 9 500 ! 9;
!CSioux 9 1 500
2 9 200
9 2 200
3 9 100
9 3 100
4 9 700
5 9 800
6 9 400
9 6 400
7 9 600
9 7 600
8 9 800
9 8 800
1 10 1300 !10;
!CSioux 10 1 1300
2 10 600
10 2 600
3 10 300
10 3 300
4 10 1200
10 4 1200
5 10 1000
10 5 1000
6 10 800
10 6 800
7 10 1900
10 7 1900
8 10 1600
10 8 1600
9 10 2800
10 9 2800
;
ENDDATA
!Compute total flow on each arc;
@FOR(Link(i,j): [Def]
TotFlo(i,j)=@SUM(Link4Dest(i,j,t): X(i,j,t))
);
!Conservation of flow,
for each origin j and destination t:
flow into j destined for t + flow originating
at j destined for t
= flow out of j destined for t;
@FOR( trip(j,t): [Origin]
@SUM(Link4Dest(i,j,t): X(i,j,t)) + Dem(j,t) =
@SUM(Link4Dest(j,k,t): X(j,k,t))
);
!Conservation of flow,
for each node j and destination t
for which j is not an origin for flow to t and j #NE# t:
flow into j destined for t = flow out of j destined for t;
@FOR( NXD(j,t) | (#NOT# @IN( Trip,j,t)) #AND# (j #NE# t) :
[Inter] @SUM( Link4Dest(i,j,t): X(i,j,t))=
@SUM( Link4Dest(j,k,t): X(j,k,t))
);
! Compute travel time on Link i,j;
@FOR( SYS | Style #EQ# 0:
@FOR( Link(i,j): [CCon0]
ArcTime(i,j) =
Bcost(i,j)*(1 + Scale*( TotFlo(i,j)/Cap(i,j))^ Power)
);
);
@FOR( SYS | Style #EQ# 1:
@FOR( Link(i,j): [CCon1]
ArcTime(i,j) =
Bcost(i,j) + ( TotFlo(i,j)* Cap( i, j))^ Power
);
);
! Enforce user equilibrium ( if UserOpt = 1);
! For destination node t, the remaining time/cost
to get there is 0;
@FOR( Dest(t)| UserOpt: R(t,t) = 0);
! For the other nodes i;
@FOR( Dest(t)| UserOpt:
@FOR( Link(i,j) | i #NE# t:
[sdf] Slk(i,j,t) = ArcTime(i,j) + R(j,t) - R(i,t);
! Complementarity constraints. If Slk(i,j,t) > 0,then
we cannot use link i,j to get to t;
Slk(i,j,t)*X(i,j,t) = 0;
);
);
! Compute system cost;
SysCost = @SUM(Link(i,j): TotFlo( i, j)*ArcTime( i, j));
! To minimize System cost or find Social optimum,
turn on the following, and turn off complemenarity constraints;
! Min = (1-UserOpt)*SysCost;
Min = SysCost;
|