Having a good understanding of arrays will make this easier to understand. Beforehand, I create an array of arrays that hold the different path variations. So the structure looks kind of like this.
var pathLists = [
[
[startPath1 + randomAltPath],
[startPath1 + randomAltPath],
[startPath1 + randomAltPath],
[startPath1 + randomAltPath],
],
[
[startPath2 + randomAltPath],
[startPath2 + randomAltPath],
[startPath2 + randomAltPath],
[startPath2 + randomAltPath],
],
[
[startPath3 + randomAltPath],
[startPath3 + randomAltPath],
[startPath3 + randomAltPath],
[startPath3 + randomAltPath],
],
[
[startPath4 + randomAltPath],
[startPath4 + randomAltPath],
[startPath4 + randomAltPath],
[startPath4 + randomAltPath],
]
]
The random alternate paths are shuffled, so there will only be 1 circle going down a certain path at a time. However, that will only happen if the duration/speed is the same for each circle for every path variation. By using a random duration for each circle/variation, there is a possibility that a fast moving circle could catch-up to a slow moving circle, and head down the same path.
Eliminating that possibility completely would require more code and logic, but we can reduce that possibility by reducing the range of the random duration. Instead of using a large range, like random(1, 5), use a smaller range like random(1.5, 2).