Group 7 - Olympic Road Race

Miguel Maldonaldo
Robert Tobkes
Ziijian Zhou


Introduction and Problem Analysis

The Olympic Road Race consists of r riders from n teams distributed randomly in l lanes, where l is bigger or equal to r*n. The objective of the race is to obtain one of the 3 medals awarded: Gold, worth 5 points; Silver, worth 3 points and Bronze, 1 point. All the players in the "Olympics" have the same athletic abilities: They all start in life with the same amount of energy, all have the same maximum speed of 25 m/s and all must accelerate or decelerate at rate no more than 1 m/s^2. Therefore winning the race is a matter of good strategies alone. Choosing a good strategy is based on the following characteristics of the race.

Energy

The energy consumption is given by v^2.5, where v is the speed of the rider at time t. Since energy consumption is quadratic and distance travelled is linear, it is not advisable to travel at very high speeds. Neither is advantageous to travel at low speeds first and then speed up to recover lost distance, due to the higher costs of higher speeds. The most advantageous strategy in terms of energy consumption is to maintain a constant speed for the entire race. Also, any rider that finishes the race with energy left over has essentially wasted this energy; this rider should have rode faster and used this energy instead.

"Optimal" Speed

The parameters of the problem are restricted such that it is not possible for the riders to go at full speed for the entirety of the race. If a rider travels too fast, he would have used too much energy and would not be able to finish the race. Therefore there must be a steady speed that the riders can travel in order to complete the race in the shortest amount of time.

Slip Stream Advantage.

It is possible for riders to be shielded from the wind resistance by riding behind another rider. This reduces exposure to wind resistance, results in less energy consumption. The energy consumption in the presence of slip stream is given as: v^2.5 * (1-((5-d)/10)) where d is the distance between the rider and the rider in front of him. The formula shows that any rider further than 5 meters behind will not benefit from this slipstream advantage.

Lane Changes

Because of the slip stream advanatage previously discussed, it is always favorable to ride behind another rider. It is possible for riders from other teams to ride behind the rider's from our team; we would be giving our competitors a 30% bonus! The riders from the other teams will save energy and possibly beat our winning rider in the last leg of the race by accelerating using energy it had saved. Since there is no penalty for changing lanes, it is a way to avoid giving other teams a free ride on our slipstream.

Disruption

It is possible that other riders can disrupt our strategies by preventing our players from making desired lane changes and by preventing our riders from accelerating to their desired speeds. Also riders from other teams can slow down and effectively cause all of our riders to stop.

The Optimal Strategy

Based on the said race characteristics, the optimal strategy is to move all of our riders to the same lane and form a column, ideally they are each 2 meters apart. This way, out of N riders in the column, N-1 of them will have the slip stream advantage. Collectively, our riders can travel at a much faster speed than each of them individually. All the riders should travel at least at the same speed as the leading rider in order to keep formation intact. This speed should be set, such that over the course of the race the first N-1 riders die, leaving the Nth rider to cross the finish line using his last bit of energy. In this strategy, no energy is wasted and the slipstream advantage is taken as much as possible.

However, while in a column, the aforementioned disruptions can take place. So riders must also be able to detect any damaging behavior and act accordingly by changing lanes if possible.


Player Strategies


Line Dancing:

Line Dancing is our player who follows the rules of the above optimal strategy.

Meeting Lane

The first task in creating a column player is finding the desired meeting lane. There are two obvious choices: the mean or the median of the starting lanes. The advantage of using the median lane is that we are certain that no other teams can start out in this lane; our team has first rights to this lane. However, other riders from our team will have to travel further to reach the median lane as opposed to the mean lane. Due to the congestion at the start of the race and the subsequent difficulties in making lane changes, we decided to use the mean lane as our meeting lane.

Speed

The speed of each rider is calculated using the formula suggested by Bogdan, namely:
Current Energy / Current Distance * (10/7) * (1 - 0.3 ^ (Number of Riders Currently in the Column))
Every turn we recalculate our desired speed by the formula and adjust the acceleration of each rider accordingly.

Caveat on Speed (Initial Speed While Lining Up)

If the Line Dancing riders were to ride at the optimal speed while trying to form a line, many of the desired lane changes would be blocked because many riders from other teams are also going at this speed. Our first method to avoid these conflicts was to subtract 0.05 from our desired acceleration so that overtime we would eventually fall behind the other line players and be able to form our own line. However, this strategy has two pitfalls. One, by subtracting such a small amount, it takes many turns to fall behind the other players, thus extending the time that our riders were not saving energy by slipstreaming. Second, by using a constant, other teams could easily match our speed and prevent the lane changes. Our second method was to subtract a random number between 0 and .5 from our acceleration. By slowing down more initially, we could form a column quicker than other groups and thus make up for being behind. However, the pitfall of this strategy is, there was too much of a distance to overcome. Our final strategy is a compromise of the first two. To start, our players ride at the optimal speed, and then slow down only when they are one lane away from the meeting lane to insure that they will be able to immediately fall into line. In this case we set our acceleration be a anywhere from .5-1m/s^s less than the optimal acceleration. Because of minor differences in the way each group calculated the optimal speed, and the minor differences in energy of each player, our player was separated enough from the other players. For example, in the picture below, by turn 28, each team is far enough from the other teams that the riders have the ability to easily maneuver.

The Fudge Factor

After coding our player Line Dancing to the optimal algorithm, it was dying "on the finish line" so we needed to alter the parameters given the function that calculates the optimal acceleration. There were two obvious choices: either increase the race length or decrease our actual position. We implemented both and experienced a more stable player when increasing the race length (decreasing our distance did not always lead to finishing the race). So now we had to decide on the amount to increase the race length. At first we used a hard-coded value of five meters, but soon realized this would not do because in a shorter race, such an increase would have much larger effects. Instead, we scaled our fudge factor to the race length, using five as the fudge factor for a 180 kilometer race to calculate the percent. Therefore, our fudge factor is .01%, unless .01% is less than one; in that case, we use a hard-coded fudge factor of 2 meters.

Being Neatly Aligned

Once all of Line Dancing's racers converged in the same line, we had to make sure that they were in a tight column with each racer, each have to be close enough to the rider in front to take advantage of the slipstream. This is an essential part of the line strategy because any rider not in a slipstream is wasting energy fighting the wind. In order to ensure our players were tightly aligned, we used the following algorithm.

     Sort our riders based on their positions;
         //rider[0] represents the first rider and rider[n] the last
         For (int i = 1; i < n; i++)
             if (position of rider[i] + 2) < position of rider[i-1]
                     set acc of riders i through n to the max value of 1

Basically, starting from the rider behind the leader, check all riders looking for any rider that is not with two meters of the rider ahead of it. If one is found, that rider, and all the riders behind it, must speed up to catch up. The leader, and all riders tightly behind the leader, continues to race at the optimal velocity. The picture on the left represents our riders just after they have converged in the meeting lane. They are spread out and all riders are not in slipstreams. The picture on the right shows our riders tightly aligned after repeated applications of this algorithm

           

Moving Away to Prevent Disruption

We noticed that soon after our initial column was formed, the middle lanes would be very congested while the lanes close to the sides were empty. The red cirlces in the following picture clearly show this plethora of open space.


So in an effort to find free space, Line Dancing moves to the third lane from whichever side of the board our line is on. The benefits of moving away from the congestion are, it would be easier to make lane changes that keeps the integrity of the column; basically, there would be less players to interfere with our strategy. Since there is no cost in lane changes, it would be in our best interest to stay away from the action. To achieve this, we maintain our optimal speed and move synchronously. However, as seen in the picture, the chasing players can follow Line Dancing into the open space as well (Yes, this "chaser" is in an early stage of development and is ahead of our player, but it did indeed follow us into the open space).


Changing Lanes to Prevent Disruption

However, the above moving away strategy does not ensure that no other teams will disrupt our riders. We also had to implement an algorithm that dictates our lane changing behavior, by examining only the current lane and lanes on either side of us. We check to see if any riders from other teams are 5 feet in front of our lead rider (a potential blocker), or 5 feet of our last rider (a rider taking advantage of our slip stream) or anywhere in between (a chasing opponent that somehow was able to merge with our players). If the rider is in our lane, Line Dancing will change lanes. If the rider is riding right next to our column, it is not causing us any immediate harm, so we record its direction and do not change lanes. If on the next turn, we see this rider in our lane or at a distance where it can block us, we then change lanes. This algorithm also ensures that no rider can stay in the middle of our line. Furthermore, when making our line changes, we check the lane we wish to move into, has enough space to fit our column. Otherwise line change might disrupt our column formation, consider if one rider from another team is in the lane we wish to move into, blocking 1 of our riders from making the lane change, while the other N-1 riders can make the change, effectively breaking our line.


The Piggy Back Player:

We developed Piggy Back in an attempt to exploit the benefits of slip streams from other teams. The player has two main states: one, when it is chasing a player and two, when it is trying to find a player to chase.

Speed

The base speed of each rider is calculated independently using the base formula (suggested by Jeff):

(Current Energy / Current Distance) ^ (2/3).

This value is calculated in every turn during the race. When trying to find a rider to chase, our rider speeds up to this value and would only chase riders that are going at least at 70% of the calculated speed. Once we are following a rider, we can go up to twice this value, but only if a piggy back rider has at least half of its original energy.

Selecting Riders to Follow

This is the central part of our player design. Trying to exploit the very limited slip stream is very challenging. Our goal is to slip behind another rider in the least amount of moves. Travelling at a lower speed at the start of the race might seem beneficial. However, in reality it costs more to have a sluggish start than to speed up upfront and wait if necessary for others. Allowing other riders go faster could lead to situations where a piggy back rider never catches up. Furthermore, piggy back riders would not have benefitted from the slip stream. Therefore, piggy back riders will always try to travel at their base speed and then they will try if possible to identify a player in the closest two lanes to follow. The player we are trying to follow, must be travelling not too different from our base speed. Some of the player in the race have strategies where they switch lanes to prevent piggy back from benefitting from their slip stream; Piggy back riders will avoid those players. And if a suitable rider to follow is not identified on the selection process, piggy back riders will move at their base speeds and change lane with a small probability.

Following a Rider

Once we have identified a rider to follow, we must get in our positions to benefit from the slip streams. Since there is no coordination across different teams, it is more challenging to converge all the piggy back rider behind a team. However not being able to converge our piggy back players, would mean that we are causing disruption for many teams. Since many teams wait for their desired formation to be created before attempting to implemented their optimal strategy. A piggy back rider can easily disturb their formation, thus affecting their performace negatively.

We discovered that a group of riders intentionally slowed down in a effort to block players behind them. To prevent us being blocked while following, we immediately change lanes and speed up if we see a decrease in our speed. This ensures our scheme from being disrupted by more malicious players.

Race to the Finish

The final part of our piggy back strategy was the end of the race dash. The idea behind this phase is to use up the energy we were able to save by piggy backing, thus enabling us to a longer final sprint. At every move, a piggy back player will verify if he had enough energy to accelerate to the maximum speed and still cross the finish line. During the final sprint, we will switch lanes when another player is encountered.

We believe that if more time was given on this project, we would have improved our player by coordinating the final sprint in relation to the player we were following. Using the maximum speed as the base for the sprint calculation made it really hard for our player to successfully reach this state in most of the race settings. We believe that using a formula that takes into consideration the energy difference between our player and the player we were following, would had allowed us to have a more stable player. As an improvement to the specification of the project, we believe that a more realistic slip stream, where an energy savings can be achieved from riding next to the victim would have served piggy back well.

Under the current conditions, we believe that our piggy back players would most likely end with bronze medals. Since it is really hard to pass a player when he is very close to the finishing line and since the maximum amount of energy gains in the slip stream is 30%, there is a limit in the usefulness of slip streaming a rider from another team.


Tournament Results

The following results table shows the ranking of our players in different tournaments based on average score. The first column of our table shows the tournament conditions, the second column shows the rankings of Line Dancing in that tournament and the third shows the rankings of Piggy Back Rider.

Tournament Name Line Dancing Piggy Back
Base Tournament 9 14
Base-R + R = 1 2 9
Base-R + R = 2 12 5
Base-R + R = 3 7 9
Base-R + R = 5 8 13
Base-R + R = 6 4 12
Base-R + R = 7 4 9
Base-R + R = 9 1 13
Base-D + D = 30L 1 2
Base-L + L = 2*T*R 7 14
Base-E + E ~ 124*D 5 1
Base-E + E ~ 5*D 8 12
Base-T + T = 2 5 13
Base-T + T = 4 8 14


Our best tournament is clearly the one where D=30*L where we believe that the Piggy Back player followed Line Dancing to victory. Line Dancing performed very well on its own. Out of the 14 tournaments and 16 teams, Lane Dancing placed first twice, second once, fourth twice, fifth twice, as shown in the chart above. Line Dancing was among the top five racers in 50% of the tournaments. Line Dancing only finished outside the top half twice, with a lowest rank of 12. Summing all the ranks from each tournament except the special two, we see that Line Dancing ranks 5th overall, with a total score of 81, where the lowest achievable score would be 12 if a player ranked first in each of the 12 regular tournaments.

Piggy Back player behaved as we expected. He was not a major tournament winner, but in 14 of 16 tournaments our player was able to win at least one medal, including various golds. He seemed to perform very well in short races. Apparently having the check to allow our player to sprint to the maximum speed when necessary prove more valuable than previously considered.

As stated earlier, Line Dancing finished first twice. In fact, only 7 groups finished first at all, and 3 of them only once. The chart below illustrates the number of first place finishes for each team. By this standard, Line Dancing is tied for third place.


Conclusion

We approached this road race problem in two ways: one was morally pure, where we would only concentrate on winning the race cleanly and fairly; another one was more deceitful, where we used various techniques to disrupt other peoples strategies. Since we knew that these were incompatible concepts, we set to create 2 vastly different players. Each player had desirable results, as seen in the results section.

We believe that additional modifications can be made to the problem to make this a more challenging and interesting project. For instance, letting the slip stream of the columns to have an energy savings effect on the riders riding next to them. Or letting the riders behind see the movement changes of the riders ahead of them, since this reflect more clearly a race in the real world and would make our Piggy Back player more competitive.


Summary of Contributions

Line Dancing is the work of Rob Tobkes and Zijian Zhou while the Piggy Back Player is the work of Miguel Maldonaldo.
All three of the above discussed high level ideas about each player.
This document is a collaborative effort from Rob Tobkes, Zijian Zhou, and Miguel Maldonaldo.