## ams_version=1.0 Model Main_Traffic_Equilibrium { Comment: { "Keywords: Braess's paradox, Non-cooperative Game, Mixed Complementarity Problem (MCP), Stackelberg Game, Mathematical Programs with Complementarity Constraints (MPCC), PATH, KNITRO, Network Object." } DeclarationSection Traffic_Equilibrium_Declaration { Set Locations { Text: "Set containing all locations"; Index: o, d, i, j; Parameter: Origin, Destination; } Set RoadSegment { SubsetOf: (Locations, Locations); Text: "The set containing all roadsegments"; Index: a; } Set Routes { Text: "The set of all routes between all locations"; Index: r; } Parameter Demand { IndexDomain: (o,d); Text: "The amount of traffic between o and d"; } Parameter RoadPathIncidence { IndexDomain: (a,r); Text: "Road a is on route r"; } Parameter ODPathIncidence { IndexDomain: (o,d,r); Text: "r is a route between o and d"; } Parameter RoadLength { IndexDomain: (a); Text: "The length of road a"; } Parameter RoadCapacity { IndexDomain: (a); Text: "The capacity of road a"; } ComplementarityVariable Traffic { IndexDomain: (r); Text: "The traffic that flows along route r"; Range: nonnegative; Complement: { sum( a | RoadPathIncidence(a,r), RoadLength(a) * exp[ RoadTraffic(a) / RoadCapacity(a)] + if IncludeTollRoads then 500 * TollFee(a) endif ) >= sum( (o,d) | ODPathIncidence(o,d,r), MinCost(o,d)) } } Variable RoadTraffic { IndexDomain: (a); Text: "The traffic that flows along road a"; Range: nonnegative; Definition: sum( r | RoadPathIncidence(a,r),Traffic(r)); } Parameter RoadCost { IndexDomain: (a); Text: "Cost of using road a"; Definition: RoadLength(a) * exp[ RoadTraffic(a) / RoadCapacity(a)]; } Variable MinCost { IndexDomain: (o,d) | Demand(o,d); Text: "The minimal costs for traffic between o and d"; Range: nonnegative; } Constraint SatisfyDemand { IndexDomain: (o,d) | Demand(o,d); Definition: sum( r | ODPathIncidence(o,d,r) , Traffic(r)) = Demand(o,d); } MathematicalProgram TrafficEquilibrium { Constraints: TrafficEquilibriumConstraints; Variables: TrafficEquilibriumVariables; Type: MCP; } Set TrafficEquilibriumConstraints { SubsetOf: AllConstraints; Text: "The set of constraints that are used in TrafficEquilibrium"; Definition: data { Traffic, RoadTraffic, SatisfyDemand }; } Set TrafficEquilibriumVariables { SubsetOf: AllVariables; Text: "The set of variables that are used in TrafficEquilibrium"; Definition: data { Traffic, RoadTraffic, MinCost }; } StringParameter NetworkDescription { Text: "Title of newtork object"; Definition: { FormatString("Distribution of the traffic (%n units) that goes from %e to %e", demand(Origin, Destination),Origin, Destination); } } } DeclarationSection Traffic_Equilibrium_with_Toll_Roads_Declaration { Parameter IncludeTollRoads { Text: "This flag is t indicate that the current model includes toll roads"; } MathematicalProgram TrafficEquilibriumWithToll { Objective: TotalFeeIncome; Direction: maximize; Constraints: AllConstraints; Variables: AllVariables; Type: MPCC; } Variable TollFee { IndexDomain: (a) | TolledArcs(a); Text: "The toll fee for the arcs on which it is allowed to obtain toll fee"; Range: [TollFeeLowerBound, TollFeeUpperBound]; } Variable TotalFeeIncome { Text: "The total income of the toll fees"; Definition: { sum( a | TolledArcs(a), TollFee(a) * RoadTraffic(a) ); } } Parameter TollFeeLowerBound { Text: "The lower bound of the toll fee"; } Parameter TollFeeUpperBound { Text: "The upper bound of the toll fee"; } Parameter TolledArcs { IndexDomain: (a); Text: "The arcs on which it is allowed to obtain a toll fee"; } Parameter RoadTrafficWithToll { IndexDomain: (a); Text: "The actual traffic in the solution of the model with toll"; } Parameter RoadTrafficWithoutToll { IndexDomain: (a); Text: "The actual traffic in the solution of the model without toll"; } Parameter AverageCostWithToll { IndexDomain: (o,d); Text: "The average travel cost in the solution of the model with toll"; } Parameter AverageCostWithoutToll { IndexDomain: (o,d); Text: "The average travel cost in the solution of the model with toll"; } } DeclarationSection Interface_Declaration { Comment: "The declaration in this section are only used for display in the network object"; Parameter ArcTraffic { IndexDomain: (i,j,o,d); Text: "Traffic that goes along (i,j) for demand between o and d"; Definition: sum[(r) | RoadPathIncidence(i,j,r) and ODPathIncidence(o,d,r), Traffic(r)]; } Parameter Xnode { IndexDomain: (o); Text: "X-coordinate for node o in network"; } Parameter Ynode { IndexDomain: (o); Text: "Y-coordinate for node o in network"; } ElementParameter ACase { Range: AllCases; } } Procedure MainInitialization { Body: { empty Main_Traffic_Equilibrium; read from file "Initial Data.txt"; Origin := first(Locations); Destination := last(Locations); } } Procedure MainExecution { Body: { for IndexSolvers do if FindString(SearchString : FormatString("%e",IndexSolvers),Key : "PATH",CaseSensitive : 0) or FindString(SearchString : FormatString("%e",IndexSolvers),Key : "KNITRO",CaseSensitive : 0) then IncludeTollRoads := 0; solve TrafficEquilibrium; RoadTrafficWithoutToll(a) := RoadTraffic(a); AverageCostWithoutToll((o,d) | Demand(o,d)) := average( r | Traffic(r) and ODPathIncidence(o,d,r), sum((a) | RoadPathIncidence(a,r), RoadLength(a) * exp[ RoadTraffic(a) / RoadCapacity(a)])); return; endif; endfor; DialogMessage("Please install Path or Knitro in order to solve MCP.", "No Valid Solver Found"); } } Procedure SolveTrafficEquilibriumWithToll { Body: { for IndexSolvers do if FindString(FormatString("%e",IndexSolvers),"KNITRO",CaseSensitive : 0) then TollFee(a) := (TollFeeUpperBound + TollFeeLowerBound)/2; TollFee.nonvar(a) := 0; IncludeTollRoads := 1; solve TrafficEquilibriumWithToll; RoadTrafficWithToll(a) := RoadTraffic(a) ; AverageCostWithToll((o,d) | Demand(o,d)) := average( r | Traffic(r) and ODPathIncidence(o,d,r), sum((a) | RoadPathIncidence(a,r), RoadLength(a) * exp[ RoadTraffic(a) / RoadCapacity(a)])); IncludeTollRoads := 0; return; endif; endfor; DialogMessage("Please install Knitro in order to solve MPCC.", "No Valid Solver Found"); } } Procedure MainTermination { Body: { return 1; } } }