Wow, really cool things in this challenge. I took a stab at this at in C# and generated a 4096x4096 image in about 3 minutes (i7 CPU) using every single color via Random Walk logic. 

Ok, so for the code. After being frustrated with hours of research and trying to generate every single HSL color using for loops in code, I settled for creating a flat file to read HSL colors from. What I did was create every single RGB color into a List, then I ordered by Hue, Luminosity, then Saturation. Then I saved the List to a text file. ColorData is just a small class I wrote that accepts an RGB color and also stores the HSL equivalent. This code is a HUGE RAM eater. Used about 4GB RAM lol.

    
    public class RGB
    {
        public double R = 0;
        public double G = 0;
        public double B = 0;
        public override string ToString()
        {
            return "RGB:{" + (int)R + "," + (int)G + "," + (int)B + "}";
        }
    }
    public class HSL
    {
        public double H = 0;
        public double S = 0;
        public double L = 0;
        public override string ToString()
        {
            return "HSL:{" + H + "," + S + "," + L + "}";
        }
    }
    public class ColorData
    {
        public RGB rgb;
        public HSL hsl;
        public ColorData(RGB _rgb)
        {
            rgb = _rgb;
            var _hsl = ColorHelper._color_rgb2hsl(new double[]{rgb.R,rgb.G,rgb.B});
            hsl = new HSL() { H = _hsl[0], S = _hsl[1], L = _hsl[2] };
        }
        public ColorData(double[] _rgb)
        {
            rgb = new RGB() { R = _rgb[0], G = _rgb[1], B = _rgb[2] };
            var _hsl = ColorHelper._color_rgb2hsl(_rgb);
            hsl = new HSL() { H = _hsl[0], S = _hsl[1], L = _hsl[2] };
        }
        public override string ToString()
        {
            return rgb.ToString() + "|" + hsl.ToString();
        }
        public int Compare(ColorData cd)
        {
            if (this.hsl.H > cd.hsl.H)
            {
                return 1;
            }
            if (this.hsl.H < cd.hsl.H)
            {
                return -1;
            }

            if (this.hsl.S > cd.hsl.S)
            {
                return 1;
            }
            if (this.hsl.S < cd.hsl.S)
            {
                return -1;
            }

            if (this.hsl.L > cd.hsl.L)
            {
                return 1;
            }
            if (this.hsl.L < cd.hsl.L)
            {
                return -1;
            }
            return 0;
        }
    }
    public static class ColorHelper
    {


        public static void MakeColorFile(string savePath)
        {
            List<ColorData> Colors = new List<ColorData>();
            System.IO.File.Delete(savePath);
           
            for (int r = 0; r < 256; r++)
            {
                for (int g = 0; g < 256; g++)
                {
                    for (int b = 0; b < 256; b++)
                    {
                        double[] rgb = new double[] { r, g, b };
                        ColorData cd = new ColorData(rgb);
                        Colors.Add(cd);
                    }
                }
            }
            Colors = Colors.OrderBy(x => x.hsl.H).ThenBy(x => x.hsl.L).ThenBy(x => x.hsl.S).ToList();

            string cS = "";
            using (System.IO.StreamWriter fs = new System.IO.StreamWriter(savePath))
            {
                
                foreach (var cd in Colors)
                {
                    cS = cd.ToString();
                    fs.WriteLine(cS);
                }
            }
        }
        

        public static IEnumerable<Color> NextColorHThenSThenL()
        {
            HashSet<string> used = new HashSet<string>();
            double rMax = 720;
            double gMax = 700;
            double bMax = 700;
            for (double r = 0; r <= rMax; r++)
            {
                for (double g = 0; g <= gMax; g++)
                {
                    for (double b = 0; b <= bMax; b++)
                    {
                        double h = (r / (double)rMax);
                        double s = (g / (double)gMax);
                        double l = (b / (double)bMax);
                        var c = _color_hsl2rgb(new double[] { h, s, l });
                        Color col = Color.FromArgb((int)c[0], (int)c[1], (int)c[2]);
                        string key = col.R + "-" + col.G + "-" + col.B;
                        if (!used.Contains(key))
                        {
                            used.Add(key);
                            yield return col;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
            }
        }

        public static Color HSL2RGB(double h, double s, double l){
            double[] rgb= _color_hsl2rgb(new double[] { h, s, l });
            return Color.FromArgb((int)rgb[0], (int)rgb[1], (int)rgb[2]);
        }
        public static double[] _color_rgb2hsl(double[] rgb)
        {
            double r = rgb[0]; double g = rgb[1]; double b = rgb[2];
            double min = Math.Min(r, Math.Min(g, b));
            double max = Math.Max(r, Math.Max(g, b));
            double delta = max - min;
            double l = (min + max) / 2.0;
            double s = 0;
            if (l > 0 && l < 1)
            {
                s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
            }
            double h = 0;
            if (delta > 0)
            {
                if (max == r && max != g) h += (g - b) / delta;
                if (max == g && max != b) h += (2 + (b - r) / delta);
                if (max == b && max != r) h += (4 + (r - g) / delta);
                h /= 6;
            } return new double[] { h, s, l };
        }


        public static double[] _color_hsl2rgb(double[] hsl)
        {
            double h = hsl[0];
            double s = hsl[1];
            double l = hsl[2];
            double m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
            double m1 = l * 2 - m2;
            return new double[]{255*_color_hue2rgb(m1, m2, h + 0.33333),
               255*_color_hue2rgb(m1, m2, h),
               255*_color_hue2rgb(m1, m2, h - 0.33333)};
        }


        public static double _color_hue2rgb(double m1, double m2, double h)
        {
            h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
            if (h * (double)6 < 1) return m1 + (m2 - m1) * h * (double)6;
            if (h * (double)2 < 1) return m2;
            if (h * (double)3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * (double)6;
            return m1;
        }


    }

With that out of the way. I wrote a class to get the next color from the generated file. It lets you set the hue start and hue end. In reality, that could and should probably be generalized to whichever dimension the file was sorted by first. Also I realize that for a performance boost here, I could have just put the RGB values into the file and kept each line at a fixed length. That way I could have easily specified the byte offset instead of looping through every line until I reached the line I wanted to start at. But it wasn't that much of a performance hit for me. But here's that class

    
    public class HSLGenerator
    {

        double hEnd = 1;
        double hStart = 0;

        double colCount = 256 * 256 * 256;

        public static Color ReadRGBColorFromLine(string line)
        {
            string sp1 = line.Split(new string[] { "RGB:{" }, StringSplitOptions.None)[1];
            string sp2 = sp1.Split('}')[0];
            string[] sp3 = sp2.Split(',');
            return Color.FromArgb(Convert.ToInt32(sp3[0]), Convert.ToInt32(sp3[1]), Convert.ToInt32(sp3[2]));
        }
        public IEnumerable<Color> GetNextFromFile(string colorFile)
        {
            int currentLine = -1;
            int startLine = Convert.ToInt32(hStart * colCount);
            int endLine = Convert.ToInt32(hEnd * colCount);
            string line = "";
            using(System.IO.StreamReader sr = new System.IO.StreamReader(colorFile))
            {

                while (!sr.EndOfStream)
                {
                    line = sr.ReadLine();
                    currentLine++;
                    if (currentLine < startLine) //begin at correct offset
                    {
                        continue;
                    }
                    if (currentLine >= endLine) //non-inclusive endLine
                    {
                        break;
                    }
                    yield return ReadRGBColorFromLine(line);
                }
        }

        HashSet<string> used = new HashSet<string>();

        public void SetHueLimits(double hueStart, double hueEnd)
        {
            hEnd = hueEnd;
            hStart = hueStart;
        }
    }


So now that we have the color file, and we have a way to read the file, we can now actually make the image. I used a class I found to boost performance of setting pixels in a bitmap, called LockBitmap. [LockBitmap source][1]

I created a small Vector2 class to store coordinate locations

    
    public class Vector2
    {
        public int X = 0;
        public int Y = 0;
        public Vector2(int x, int y)
        {
            X = x;
            Y = y;
        }
        public Vector2 Center()
        {
            return new Vector2(X / 2, Y / 2);
        }
        public override string ToString()
        {
            return X.ToString() + "-" + Y.ToString();
        }
    }

And I also created a class called SearchArea, which was helpful for finding neighboring pixels. You specify the pixel you want to find neighbors for, the bounds to search within, and the size of the "neighbor square" to search. So if the size is 3, that means you're searching a 3x3 square, with the specified pixel right in the center.

    
    public class SearchArea
    {
        public int Size = 0;
        public Vector2 Center;
        public Rectangle Bounds;

        public SearchArea(int size, Vector2 center, Rectangle bounds)
        {
            Center = center;
            Size = size;
            Bounds = bounds;
        }
        public bool IsCoordinateInBounds(int x, int y)
        {
            if (!IsXValueInBounds(x)) { return false; }
            if (!IsYValueInBounds(y)) { return false; }
            return true;

        }
        public bool IsXValueInBounds(int x)
        {
            if (x < Bounds.Left || x >= Bounds.Right) { return false; }
            return true;
        }
        public bool IsYValueInBounds(int y)
        {
            if (y < Bounds.Top || y >= Bounds.Bottom) { return false; }
            return true;
        }

    }

Here's the class that actually chooses the next neighbor. Basically there's 2 search modes. A) The full square, B) just the perimeter of the square. This was an optimization that I made to prevent searching the full square again after realizing the square was full. The DepthMap was a further optimization to prevent searching the same squares over and over again. However, I didn't fully optimize this. Every call to GetNeighbors will always do the full square search first. I know I could optimize this to only do the perimeter search after completing the initial full square. I just didn't get around to that optimization yet, and even without it the code is pretty fast. The commented out "lock" lines are because I was using Parallel.ForEach at one point, but realized I had to write more code than I wanted for that lol.

    
    public class RandomWalkGenerator
    {
        HashSet<string> Visited = new HashSet<string>();
        Dictionary<string, int> DepthMap = new Dictionary<string, int>();
        Rectangle Bounds;
        Random rnd = new Random();
        public int DefaultSearchSize = 3;
        public RandomWalkGenerator(Rectangle bounds)
        {
            Bounds = bounds;
        }
        private SearchArea GetSearchArea(Vector2 center, int size)
        {
            return new SearchArea(size, center, Bounds);
        }

        private List<Vector2> GetNeighborsFullSearch(SearchArea srchArea, Vector2 coord)
        {
            int radius = (int)Math.Floor((double)((double)srchArea.Size / (double)2));
            List<Vector2> pixels = new List<Vector2>();
            for (int rX = -radius; rX <= radius; rX++)
            {
                for (int rY = -radius; rY <= radius; rY++)
                {
                    if (rX == 0 && rY == 0) { continue; } //not a new coordinate
                    int x = rX + coord.X;
                    int y = rY + coord.Y;
                    if (!srchArea.IsCoordinateInBounds(x, y)) { continue; }
                    var key = x + "-" + y;
                    // lock (Visited)
                    {
                        if (!Visited.Contains(key))
                        {
                            pixels.Add(new Vector2(x, y));
                        }
                    }
                }
            }
            if (pixels.Count == 0)
            {
                int depth = 0;
                string vecKey = coord.ToString();
                if (!DepthMap.ContainsKey(vecKey))
                {
                    DepthMap.Add(vecKey, depth);
                }
                else
                {
                    depth = DepthMap[vecKey];
                }

                var size = DefaultSearchSize + 2 * depth;
                var sA = GetSearchArea(coord, size);
                pixels = GetNeighborsPerimeterSearch(sA, coord, depth);
            }
            return pixels;
        }
        private Rectangle GetBoundsForPerimeterSearch(SearchArea srchArea, Vector2 coord)
        {
            int radius = (int)Math.Floor((decimal)(srchArea.Size / 2));
            Rectangle r = new Rectangle(-radius + coord.X, -radius + coord.Y, srchArea.Size, srchArea.Size);
            return r;
        }
        private List<Vector2> GetNeighborsPerimeterSearch(SearchArea srchArea, Vector2 coord, int depth = 0)
        {
            string vecKey = coord.ToString();
            if (!DepthMap.ContainsKey(vecKey))
            {
                DepthMap.Add(vecKey, depth);
            }
            else
            {
                DepthMap[vecKey] = depth;
            }
            Rectangle bounds = GetBoundsForPerimeterSearch(srchArea, coord);
            List<Vector2> pixels = new List<Vector2>();
            int depthMax = 1500;

            if (depth > depthMax)
            {
                return pixels;
            }

            int yTop = bounds.Top;
            int yBot = bounds.Bottom;

            //left to right scan
            for (int x = bounds.Left; x < bounds.Right; x++)
            {

                if (srchArea.IsCoordinateInBounds(x, yTop))
                {
                    var key = x + "-" + yTop;
                    // lock (Visited)
                    {
                        if (!Visited.Contains(key))
                        {
                            pixels.Add(new Vector2(x, yTop));
                        }
                    }
                }
                if (srchArea.IsCoordinateInBounds(x, yBot))
                {
                    var key = x + "-" + yBot;
                    // lock (Visited)
                    {
                        if (!Visited.Contains(key))
                        {
                            pixels.Add(new Vector2(x, yBot));
                        }
                    }
                }
            }

            int xLeft = bounds.Left;
            int xRight = bounds.Right;
            int yMin = bounds.Top + 1;
            int yMax = bounds.Bottom - 1;
            //top to bottom scan
            for (int y = yMin; y < yMax; y++)
            {
                if (srchArea.IsCoordinateInBounds(xLeft, y))
                {
                    var key = xLeft + "-" + y;
                    // lock (Visited)
                    {
                        if (!Visited.Contains(key))
                        {
                            pixels.Add(new Vector2(xLeft, y));
                        }
                    }
                }
                if (srchArea.IsCoordinateInBounds(xRight, y))
                {
                    var key = xRight + "-" + y;
                    // lock (Visited)
                    {
                        if (!Visited.Contains(key))
                        {
                            pixels.Add(new Vector2(xRight, y));
                        }
                    }
                }
            }

            if (pixels.Count == 0)
            {
                var size = srchArea.Size + 2;
                var sA = GetSearchArea(coord, size);
                pixels = GetNeighborsPerimeterSearch(sA, coord, depth + 1);
            }
            return pixels;
        }
        private List<Vector2> GetNeighbors(SearchArea srchArea, Vector2 coord)
        {
            return GetNeighborsFullSearch(srchArea, coord);
        }
        public Vector2 ChooseNextNeighbor(Vector2 coord)
        {
            SearchArea sA = GetSearchArea(coord, DefaultSearchSize);
            List<Vector2> neighbors = GetNeighbors(sA, coord);
            if (neighbors.Count == 0)
            {
                return null;
            }
            int idx = rnd.Next(0, neighbors.Count);
            Vector2 elm = neighbors.ElementAt(idx);
            string key = elm.ToString();
            // lock (Visited)
            {
                Visited.Add(key);
            }
            return elm;
        }
    }

Ok great, so now here's the class that creates the image

    
    
    public class RandomWalk
    {
        Rectangle Bounds;
        Vector2 StartPath = new Vector2(0, 0);
        LockBitmap LockMap;
        RandomWalkGenerator rwg;
        public int RandomWalkSegments = 1;
        string colorFile = "";

        public RandomWalk(int size, string _colorFile)
        {
            colorFile = _colorFile;
            Bounds = new Rectangle(0, 0, size, size);
            rwg = new RandomWalkGenerator(Bounds);
        }
        private void Reset()
        {
            rwg = new RandomWalkGenerator(Bounds);
        }
        public void CreateImage(string savePath)
        {
            Reset();
            Bitmap bmp = new Bitmap(Bounds.Width, Bounds.Height);
            LockMap = new LockBitmap(bmp);
            LockMap.LockBits();
            if (RandomWalkSegments == 1)
            {
                RandomWalkSingle();
            }
            else
            {
                RandomWalkMulti(RandomWalkSegments);
            }
            LockMap.UnlockBits();
            bmp.Save(savePath);

        }
        public void SetStartPath(int X, int Y)
        {
            StartPath.X = X;
            StartPath.Y = Y;
        }
        private void RandomWalkMulti(int buckets)
        {

            int Buckets = buckets;
            int PathsPerSide = (Buckets + 4) / 4;
            List<Vector2> Positions = new List<Vector2>();

            var w = Bounds.Width;
            var h = Bounds.Height;
            var wInc = w / Math.Max((PathsPerSide - 1),1);
            var hInc = h / Math.Max((PathsPerSide - 1),1);

            //top
            for (int i = 0; i < PathsPerSide; i++)
            {
                var x = Math.Min(Bounds.Left + wInc * i, Bounds.Right - 1);
                Positions.Add(new Vector2(x, Bounds.Top));
            }
            //bottom
            for (int i = 0; i < PathsPerSide; i++)
            {
                var x = Math.Max(Bounds.Right -1 - wInc * i, 0);
                Positions.Add(new Vector2(x, Bounds.Bottom - 1));
            }
            //right and left
            for (int i = 1; i < PathsPerSide - 1; i++)
            {
                var y = Math.Min(Bounds.Top + hInc * i, Bounds.Bottom - 1);
                Positions.Add(new Vector2(Bounds.Left, y));
                Positions.Add(new Vector2(Bounds.Right - 1, y));
            }
            Positions = Positions.OrderBy(x => Math.Atan2(x.X, x.Y)).ToList();
            double cnt = 0;
            List<IEnumerator<bool>> _execs = new List<IEnumerator<bool>>();
            foreach (Vector2 startPath in Positions)
            {
                double pct = cnt / (Positions.Count);
                double pctNext = (cnt + 1) / (Positions.Count);

                var enumer = RandomWalkHueSegment(pct, pctNext, startPath).GetEnumerator();

                _execs.Add(enumer);
                cnt++;
            }

            bool hadChange = true;
            while (hadChange)
            {
                hadChange = false;
                foreach (var e in _execs)
                {
                    if (e.MoveNext())
                    {
                        hadChange = true;
                    }
                }
            }

        }
        private IEnumerable<bool> RandomWalkHueSegment(double hueStart, double hueEnd, Vector2 startPath)
        {
            var colors = new HSLGenerator();
            colors.SetHueLimits(hueStart, hueEnd);
            var colorFileEnum = colors.GetNextFromFile(colorFile).GetEnumerator();
            Vector2 coord = new Vector2(startPath.X, startPath.Y);
            LockMap.SetPixel(coord.X, coord.Y, ColorHelper.HSL2RGB(0, 0, 0));

            while (true)
            {
                if (!colorFileEnum.MoveNext())
                {
                    break;
                }
                var rgb = colorFileEnum.Current;
                coord = ChooseNextNeighbor(coord);
                if (coord == null)
                {
                    break;
                }
                LockMap.SetPixel(coord.X, coord.Y, rgb);
                yield return true;

            }
        }
        private void RandomWalkSingle()
        {
            Vector2 coord = new Vector2(StartPath.X, StartPath.Y);
            LockMap.SetPixel(coord.X, coord.Y, ColorHelper.HSL2RGB(0, 0, 0));
            int cnt = 1;
            var colors = new HSLGenerator();
            var colorFileEnum = colors.GetNextFromFile(colorFile).GetEnumerator();
            while (true)
            {
                if (!colorFileEnum.MoveNext())
                {
                    return;
                }
                var rgb = colorFileEnum.Current;
                var newCoord = ChooseNextNeighbor(coord);
                coord = newCoord;
                if (newCoord == null)
                {
                    return;
                }
                LockMap.SetPixel(newCoord.X, newCoord.Y, rgb);
                cnt++;

            }

        }

        private Vector2 ChooseNextNeighbor(Vector2 coord)
        {
            return rwg.ChooseNextNeighbor(coord);
        }


    }


And here's an example implementation:
    
   
    class Program
    {
        static void Main(string[] args)
        {
            {
               // ColorHelper.MakeColorFile();
              //  return;
            }
            string colorFile = "colors.txt";
            var size = new Vector2(1000,1000);
            var ctr = size.Center();
            RandomWalk r = new RandomWalk(size.X,colorFile);
            r.RandomWalkSegments = 8;
            r.SetStartPath(ctr.X, ctr.Y);
            r.CreateImage("test.bmp");

        }
    }


If RandomWalkSegments = 1, then it basically just starts walking wherever you tell it to, and begins at the first first color in the file. 

It's not the cleanest code I'll admit, but it runs pretty fast!





[![Cropped Output][2]][2]

[![3 Paths][3]][3]

[![128 Paths][4]][4]


  [1]: http://www.codeproject.com/Tips/240428/Work-with-bitmap-faster-with-Csharp
  [2]: https://i.sstatic.net/rSH7Z.jpg
  [3]: https://i.sstatic.net/cg2dV.jpg
  [4]: https://i.sstatic.net/phXbQ.jpg