G-SOC generates perfectly counterbalanced condition sequences by representing trials and their temporal relationships (i.e., preceding and following each other) as a graph. We then use the tools of graph theory to generate a sequence from the graph.
Graphs are mathematical objects that can be used to represent a wide range of problems. For instance, I could represent the world’s air travel system with the following graph representation. Each airport is a node (represented by a circle) in the graph and direct flights between them are represented by the directed edges (lines and arrows) connecting them. The numbers along each edge (i.e. weights in graph theory terminology) represent the flight time between the two cities.
The utility of graph representations derives primarily from the large body of knowledge about their properties, allowing one to reach useful conclusions about relationships between vertices of the graph. For instance, finding the shortest trip from London to Sydney in Figure 1 requires calculating the path between the two airports that has the smallest weighted sum of the traversed edges. In this case, there are only two paths through the graph from London to Sydney, and one can simply compute, by hand, that the shortest path from London to Sydney is via Hong Kong. For more complex graphs with hundreds of vertices and thousands of edges, doing it by hand isn't practical. Graph theory provides efficient algorithms for computing various types of paths through graphs and thus can solve a large number of complex optimization problems.
Your Experiment as a Graph
G-SOC uses the nodes in a graph (e.g., Figure 2) to represent your experiment's conditions and the arrows/edges represent their temporal relationships. Notice that if we have a graph with all possible edges present exactly once (as in Figure 2) then we are representing all temporal relationships between conditions equally often. That is, the edge A>B appears just as often as the edge B>A and C>A and so on.
In such a graph, imagine that we start at a node, let's say A, and take a walk around the graph such that we cross each edge exactly once. Because this walk involves all of the edges exactly once (and therefore all temporal relationships between conditions exactly once), then it will be the case that the sequence of conditions that we go through on this walk will be serially counterbalanced (i.e., each condition will be preceded by every other condition equally often). That is exactly what we want!
But how do we find such "paths" through the graph and how do we known if it is even possible? It can be done by trial and error in small graphs but larger graphs would be difficult. Luckily, the famous mathematician Leonhard Euler (pronounced Oiler) determined the conditions that indicate whether a given graph can have such a path. We now call these paths (where each edge is traversed exactly once) Euler paths (or cycles). Even more conveniently, others have developed algorithms for generating such paths. G-SOC simply converts your experiment into a graph representation and then uses what we know about graph theory to find an Euler path through that graph.
G-SOC won't work on every possible experiment because the graph representation of some experiments may not have any Euler paths (by the conditions that Euler discovered). However, in most experiments G-SOC can work, especially if your conditions appear equally often across the experiment. This is the default and you can simply use one of the G-SOC functions and input the number of conditions and how often each condition is repeated.
If you have experiments with some conditions appearing more often than others, you can still try G-SOC (but you will need to specify your own graph representation of the experiment), but it will only work if the graph has Eulerian paths.
For more information on G-SOC and details of its implementation, you can read the published paper in Psychological Methods which is freely downloadable HERE.