1

I am currently working on a project for driver scheduling and it's at the initial stage. I have decided to use GA to generate optimized schedule for a driver, and as most of GA project do, the population shall be represented in binary.

e.g. if a driver is assigned two hours of task and his working duration is 9 hours, the possible population for that specific day looks like 110000000, 011000000, 001100000 and so on.

As GA's initialization, I would like to produce possible gene like 000110000 dynamically with two parameters (working duration of driver, and duty duration).

I managed to get fully random binary code in boolean list (see below) but this is not what I want to represent as the initialization.

This is the partial code which generates random binary string (technically bunch of boolean values) in a list.

private Random Rnd = new Random();
        //initial data
    private List<bool[]> CreateInitialData()
    {
        //generate 4 random genes (might be more)
        return Enumerable.Range(0, 1).Select(_ =>
        {
            var array = new bool[GeneLength];
            for(int i = 0; i < GeneLength; i++)
            {
                array[i] = Rnd.Next(0, 2) == 1;
            }
            return array;
        }).ToList();
    }

How could I implement the initialization function to produce the binary code which meets the requirement (driver's working hours, estimated duty duration)? If there is a better way to represent it other than boolean list, please do suggest as well.

yeehui
  • 101
  • 2
  • 7
  • Are all tasks a multiple of 1 hour? The binary idea seems ok but you might need to increase the resolution to cope with unit of say 15 or 30 mins. – Dave Becker Apr 04 '17 at 12:58
  • Let's say all tasks a multiple of 1 hour for this question to make the answer neater. But you are right, thank you for pointing out! – yeehui Apr 04 '17 at 13:24
  • Just realised I missed a big part out of my answer. I'll delete and add back in.... – Dave Becker Apr 04 '17 at 13:39
  • Before I post up my new answer can I be sure that you want to: generate all permutations based on working duration and duty duration. For example for 9, 2 you want 11000000, 011000000, 001100000,000110000 etc. is that right? – Dave Becker Apr 04 '17 at 13:51
  • Thank you for your help! Yes, preferably with two parameters (driver working duration, and estimated duty duration). – yeehui Apr 04 '17 at 13:55

1 Answers1

0

Based on 1 hour tasks I came up with this:

private static void Main(string[] args)
{
    var genes = GetGenes(9, 2);
}

private static List<bool[]> GetGenes(int workinghours, int estimateddutyduration)
{
    // get the base representation 
    var hours = GetHours(workinghours, estimateddutyduration);
    var list = new List<bool[]>();
    for (int i = 0; i < (workinghours-estimateddutyduration)+1; i++)
    {
        // add
        list.Add(hours);
        // switch
        hours = SwitchArray(hours);
    }
    return list;
}

private static bool[] SwitchArray(bool[] array)
{
    // copy the array to a list
    var temp = array.ToList();
    // insert the last element at the front
    temp.Insert(0, temp.Last());
    // remove the last
    temp.RemoveAt(temp.Count-1);
    // return as array
    return temp.ToArray();
}

private static bool[] GetHours(int totalhours, int taskduration)
{
    // initialise the list
    var hours = new List<bool>(totalhours);
    // fill the list for the number of working hours
    for (int i = 0; i < totalhours; i++)
    {
        hours.Add(false);
    }
    // iterate for the task duration and set the hours as working
    for (int i = 0; i < taskduration; i++)
    {
        hours[i] = true;
    }
    // return as array
    return hours.ToArray();
}

for 9, 2 returns

110000000
011000000
001100000
000110000
000011000
000000110
000000011

for 9, 9 returns

111111111

For 9, 4 returns

111100000
011110000
001111000
000111100
000011110
000001111

This code is quite verbose and I have no doubt it can be optimized. But it's the idea I want to convey more than anything.

EDIT: If you want to display the results on the console

private static void ShowGenes(List<bool[]> genes)
{
    foreach (var gene in genes)
    {
        foreach (var bit in gene)
        {
            Console.Write(bit ? "1" : "0");
        }
        Console.Write("\n");
    }
}
Dave Becker
  • 1,433
  • 1
  • 12
  • 24
  • Thank you for your quick reply Dave! I have a few questions on this answer. I am novice in C# so please forgive me if I ask some dumb question. What does SwitchArray actually do? How did you output the results? Could I use console.write() method for that? – yeehui Apr 04 '17 at 14:30
  • `SwitchArray()` literally takes the last element and inserts it at the beginning and drops it off the end. So start with 123456789, then 9123456789 and then 912345678. Make sense? – Dave Becker Apr 04 '17 at 15:17
  • I actually wrote the results out manually!! but yeah you could easily loop through the results and write them to the console. – Dave Becker Apr 04 '17 at 15:18
  • With your input, I understand how all possible genes can be shown in c#. I can now move forward to next stage. Thank you very much! – yeehui Apr 04 '17 at 15:28
  • Excellent! Glad it helped! – Dave Becker Apr 04 '17 at 15:52