Реализация первого подобранного алгоритма

Проблема: У меня есть 3 машины, каждая машина имеет ограничение в 30 мс, каждая машина имеет 3 зоны, в которых задача не может быть выполнена. Задачи имеют приоритет P (приоритет) и W (вес, который является временем для завершения задачи в этой настройке), задачи должны быть сначала упорядочены по приоритету, от более низкого до более следующего:

Задача 01 {6, 2}//P/W = 3 эта задача выполнена последней (3)

Задача 02 {7, 7}//P/W = 1 эта задача выполнена первой (1)

Задача 03 {4, 2}//P/W = 2 эта задача выполнена второй (2)

Теперь, чтобы выполнить задачи (у меня есть 6), я должен проверить все 3 машины, чтобы найти первое соответствие задаче, выбрать подходящую для задачи, она должна быть оптимальной в трех машинах, например

Машина 01; | ----- 5 ---- 9 ------- 16-17--19-20 |

Машина 02: | ---- 4-5--7-8 --------- 17-18-- |

Машина 03: | ----- 5 --- 8--10 --- 13--15 --- 18-- |

(1) Задача 02, выполненная на машине 02 (Мы ищем P ms для выполнения задачи и минимальное время для запуска задачи, поскольку оба устройства 01 (начиная с 9 мс) и 02 (начиная с 8 мс) имеют свободное время 7 мс, машина 02 может сначала запустить задачу, затем машину 01).

(2) Задача 03, выполненная на машине 02 (Мы ищем P ms для выполнения задачи).

(3) Задача 01, выполненная в машине 01 (Мы ищем P ms для выполнения задачи).

Определенные периоды времени определяются как критические и не могут использоваться для планирования задания. Эти периоды (например, 5-9, 7-8) хранятся в выделенной структуре z_indispo.

Структура bfeet используется для хранения в начале задачи и в машине с машиной.

Я реализовал в основном весь алгоритм в C, но мои результаты отличаются от ожидаемого:

#include <stdio.h>

typedef struct _z_indispo {
    int t1;
    int t2;
} z_indispo; 

typedef struct _machines {
    int t[20]; // array represent time
    z_indispo zone[2];
} machines;

typedef struct _tache {
    int p;
    int w;
    int c; //  p/w
    int i; // Task number
} tache;

typedef struct _bfeet {
    int t; // Store the time to of ending execution by a task
    int m; // The machine responsible for executing a task.
} bfeet;

int main(int argc, char **argv)
{
    machines m[4];
    tache j[6];
    tache j_tmp;
    bfeet b[4];
    int i = 0;
    int n = 0;
    int u = 0;
    int k = 0;
    int count = 0;
    int trouver = 0;
    int f_totale = 0;
    int f[3] = {0};

    m[0].zone[0].t1 = 7;
    m[0].zone[0].t2 = 9;
    m[0].zone[1].t1 = 14;
    m[0].zone[1].t2 = 15;

    m[1].zone[0].t1 = 8;
    m[1].zone[0].t2 = 9;
    m[1].zone[1].t1 = 16;
    m[1].zone[1].t2 = 17;

    m[2].zone[0].t1 = 7;
    m[2].zone[0].t2 = 8;
    m[2].zone[1].t1 = 18;
    m[2].zone[1].t2 = 19;



    /*
     * Initialise all machines
     *   0: Represent free time.
     *  -1: Represent critical zone range.
     *  -2: Represent a task already executed. 
     */
    for(i = 0; i< 3; ++i)
    {
        for(count = 0; count < 20; ++count)
        {
            if((count >= m[i].zone[0].t1 - 1 && count <= m[i].zone[0].t2 - 1) || 
               (count >= m[i].zone[1].t1 - 1 && count <= m[i].zone[1].t2 - 1))
            {
                m[i].t[count] = -1;
            }
            else
            {
                m[i].t[count] = 0;
            }
        }
    }

    for(i = 0; i< 3; ++i)
    {
        if(i == 0)
            printf("   D(1,1)           t1    s1  D(1,2)     t2 s2  D(1,3)\n");
        else if(i == 1)
            printf("   D(2,1)              t1 s1  D(2,2)           t2 s2  D(2,3)\n");
        else if(i == 2)
            printf("   D(3,1)           t1 s1  D(3,2)                    t2 s2  D(3,3)\n");
        printf("|");
        for(count = 0; count < 20; ++count)
        {
                printf("%3d", m[i].t[count]);

        }

        printf(" |\n\n");
    }

    j[0].p = 5;
    j[0].w = 2;
    j[0].i = 1;

    j[1].p = 9;
    j[1].w = 3;
    j[1].i = 2;

    j[2].p = 6;
    j[2].w = 3;
    j[2].i = 3;

    j[3].p = 6;
    j[3].w = 4;
    j[3].i = 4;

    j[4].p = 7;
    j[4].w = 7;
    j[4].i = 5;

    /*
     * Calc C = P/W .
    */
    for(count = 0; count < 5; ++count)
    {
        j[count].c = j[count].p / j[count].w;
    }

    /*
     * Sort tasks from low to hight
     */
    for(count = 0; count < 5; ++count)
    {
        for(k = 0; k < 5 - count; ++k)
        {
            if(j[k].c > j[k + 1].c)
            {
                j_tmp = j[k + 1];
                j[k + 1] = j[k];
                j[k] = j_tmp;
            }
        }
    }


    /*printf("|%2J  |%2   P  |%2  W  | C  |\n");
    printf("_____________________\n");
    for(count = 0; count < 5; ++count)
    {
        printf("|%-4d|%-4d|%-4d|%-4d|\n", j[count].i, j[count].p, j[count].w, j[count].c);
    }

    printf("\n");*/

    /*
     * Execute tasks
     */
    while(n < 5) 
    {
        for(count = 0; count < 3; ++count)
        {
            i = 0;
            trouver = 0;
            while(i <= 20 && trouver != 1)
            {
                if(m[count].t[i] == 0) // We have a  free time to start with it.
                {
                    u = 0; // num of available indexs.
                    while(m[count].t[i] != -1 && m[count].t[i] != -2)
                    {
                        if(u == j[n].p)
                            break;

                        ++u;
                        ++i;
                    }

                    if(u < j[n].p)
                    {
                        while(m[count].t[i] == -1 && m[count].t[i] == -2) // bypass unfree unites
                            ++i;
                    }
                    else if(u == j[n].p)
                    {   
                        b[count].t = i - u;
                        b[count].m = count; // 
                        trouver = 1; // we find the Necessary unites to start a task
                    }
                }
                else
                    ++i;
            }
        }

        if(u < j[n].p)
            printf("There is no free time to execute task %d", j[n].i);
        else
        {
            // Find the minimum time in all machines to start a task
            b[3].t = b[0].t;
            b[3].m = b[0].m;
            for(count = 0; count < 3; ++count)
            {
                if(b[3].t > b[count + 1].t)
                {
                    b[3].t = b[count + 1].t;
                    b[3].m = b[count + 1].m;
                }
            }

            // Put -2 to indicate that index is unfree
            u = b[3].t + j[n].p;
            for(count = b[3].t; count < u; ++count)
            {
                m[b[3].m].t[count] = -2;
            }

            if(b[3].m == 0)
                f[0] = (b[3].t + j[n].p);
            else if(b[3].m == 1)
                f[1] = (b[3].t + j[n].p);
            else if(b[3].m == 2)
                f[2] = (b[3].t + j[n].p);

            printf("Task %d end at %-2d, machine %d.\n", j[n].i, b[3].t + j[n].p, b[3].m + 1);
        }
        ++n;
    }  

    printf("\n"); 
    f_totale = f[0] + f[1] + f[2];
    printf("F of machine 01: %d.\n", f[0]); 
    printf("F of machine 02: %d.\n", f[1]); 
    printf("F of machine 03: %d.\n", f[2]); 
    printf("Total F: %d.\n", f_totale); 
    printf("\n"); 
    /*printf("\n"); 
    for(i = 0; i< 3; ++i)
    {
        if(i == 0)
            printf("   D(1,1)           t1    s1  D(1,2)     t2 s2  D(1,3)\n");
        else if(i == 1)
            printf("   D(2,1)              t1 s1  D(2,2)           t2 s2  D(2,3)\n");
        else if(i == 2)
            printf("   D(3,1)           t1 s1  D(3,2)                    t2 s2  D(3,3)\n");
        printf("|");
        for(count = 0; count < 20; ++count)
        {
                printf("%3d", m[i].t[count]);

        }

        printf(" |\n\n");
    }*/

    return 0;
}

UPDATE: У меня теперь только две зоны недоступности на каждой машине. Я также обновил код, чтобы исправить некоторые ошибки, но я все равно получаю другой вывод, а затем этот пример: У меня есть эта зона недоступности:

m[0].zone[0].t1 = 7;
m[0].zone[0].t2 = 9;
m[0].zone[1].t1 = 14;
m[0].zone[1].t2 = 15;

m[1].zone[0].t1 = 8;
m[1].zone[0].t2 = 9;
m[1].zone[1].t1 = 16;
m[1].zone[1].t2 = 17;

m[2].zone[0].t1 = 7;
m[2].zone[0].t2 = 8;
m[2].zone[1].t1 = 18;
m[2].zone[1].t2 = 19;  

5 задач:

p | 6 9 5 7 6
w | 3 3 2 7 4 
_______________
c | 2 3 2 1 1

После заказа c:

p | 7 6 5 6 9
w | 7 4 2 3 3 
_______________
c | 1 1 2 2 3

Выполнение задач должно быть таким:

      J4                              
|_______7__9_____14_15__________| ms

Задача 04 должна заканчиваться на 7, P представляет время, необходимое для выполнения задачи.

     J5                                                    
|________8_9__________16_17_____| ms

Задача 05 должна заканчиваться на 7.

   J1        J3                                             
|_______7_8_______________18_19_| ms

Задача 01 должна заканчиваться на 6, задача 03 должна заканчиваться на 14.

ОБНОВЛЕНИЕ 02: (эта проблема исправлена)

Я заметил странное поведение в моей программе, после того как я инициализировал массив m [i].t [count], я обнаружил, что переменные, ответственные за сохранение зон недоступности, изменились: ПРИМЕЧАНИЕ. Эта проблема исправлена.

UPDATE03: (эта проблема исправлена, но с новой проблемой)

У меня есть ситуация, когда задача не может найти необходимые объединения для запуска, я никогда не получаю это сообщение "Нет свободного времени для выполнения задачи", ведь я должен получить его для задачи 2, так как он объединяет 9, и у всех машин нет такого свободного времени. Код, отвечающий за этот тест:

    for(count = 0; count < 3; ++count) // search on all machines
    {
        i = 0;
        trouver = 0;
        while(i < 20 && trouver != 1)
        {
            if(m[count].t[i] == 0) // We have a  free time to start with it.
            {
                u = 0; // num of available indexs.
                while(m[count].t[i] != -1 && m[count].t[i] != -2)
                {
                    if(u == j[n].p)
                        break;

                    ++u;
                    ++i;
                }

                if(u < j[n].p)
                {
                    while(m[count].t[i] == -1 && m[count].t[i] == -2) // bypass unfree unites
                        ++i;
                }
                else if(u == j[n].p)
                {   
                    b[count].t = i - u;
                    b[count].m = count; // 
                    trouver = 1; // we find the Necessary unites to start a task
                }
            }
            else
                ++i;
        }
    }
    /* u represent the number of continuous free time, 
       j[n].p represent the necessary time to execute the current task, n is the current task 
    if(u < j[n].p) 
        printf("There is no free time to execute task %d", j[n].i);
    else
    {
        // Find the minimum time in all machines to start a task
        b[3].t = b[0].t;
        b[3].m = b[0].m;

UPDATE04:

Теперь я вижу исключенную задачу, когда нет свободного времени для выполнения задачи, однако выход не прав, потому что я вижу задачу переопределить время периода в другой задаче:

while(n < 5) 
{
    k = 0;
    for(count = 0; count < 3; ++count)
    {
        i = 0;
        u = 0;
        trouver = 0;
        while(i < 20 && trouver != 1)
        {
            if(m[count].t[i] == 0) // We have a  free time to start with it.
            {
                //u = 0; // num of available indexs.
                if(u == j[n].p)
                    break;
                else
                {       
                    ++u;
                    ++i;
                }
            }

        if(u != j[n].p)
        {
            if((m[count].t[i] == -1 || m[count].t[i] == -2))// bypass unfree unites
            {
                u = 0;
                ++i;
            }
        }

        if(u == j[n].p)
        {   
            ++k;
            b[count].t = i - u;
            b[count].m = count; // 
            trouver = 1; // we find the Necessary unites to start a task
        }
    }
}

if(u != j[n].p)
{
    printf("There is no free time to execute task %d.\n", j[n].i);
}
else
{
    // Find the minimum time in all machines to start a task
    b[3] = b[0];
    for(count = 0; count < 3; ++count)
    {
        if(b[count].t != 0)
            if(b[3].t > b[count + 1].t)
            {
                b[3] = b[count + 1];
            }
    }

    // Put -2 to indicate that index is unfree
    u = b[3].t + j[n].p;
    for(count = b[3].t; count < u; ++count)
    {
        m[b[3].m].t[count] = -2;
    }

    if(b[3].m == 0)
        f[0] = (b[3].t + j[n].p);
    else if(b[3].m == 1)
        f[1] = (b[3].t + j[n].p);
    else if(b[3].m == 2)
        f[2] = (b[3].t + j[n].p);

    printf("Task %d end at %-2d, machine %d.\n", j[n].i, b[3].t + j[n].p, b[3].m + 1);
}

++n;

}

Вывод:

   D(1,1)           t1    s1  D(1,2)     t2 s2  D(1,3)
|  0  0  0  0  0  0 -1 -1 -1  0  0  0  0 -1 -1  0  0  0  0  0 |

   D(2,1)              t1 s1  D(2,2)           t2 s2  D(2,3)
|  0  0  0  0  0  0  0 -1 -1  0  0  0  0  0  0 -1 -1  0  0  0 |

   D(3,1)           t1 s1  D(3,2)                    t2 s2  D(3,3)
|  0  0  0  0  0  0 -1 -1  0  0  0  0  0  0  0  0  0 -1 -1  0 |

| J  | P  | W  | C  |
_____________________
|1   |5   |2   |2   |
|2   |7   |3   |2   |
|3   |8   |3   |2   |
|5   |17  |7   |2   |
|4   |16  |4   |4   |

Task 1 end at 5 , machine 1.
Task 2 end at 7 , machine 1.
Task 3 end at 8 , machine 1.
There is no free time to execute task 5.
There is no free time to execute task 4.

F of machine 01: 8.
F of machine 02: 0.
F of machine 03: 0.
Total F: 8.


   D(1,1)           t1    s1  D(1,2)     t2 s2  D(1,3)
| -2 -2 -2 -2 -2 -2 -2 -2 -1  0  0  0  0 -1 -1  0  0  0  0  0 |

   D(2,1)              t1 s1  D(2,2)           t2 s2  D(2,3)
|  0  0  0  0  0  0  0 -1 -1  0  0  0  0  0  0 -1 -1  0  0  0 |

   D(3,1)           t1 s1  D(3,2)                    t2 s2  D(3,3)
|  0  0  0  0  0  0 -1 -1  0  0  0  0  0  0  0  0  0 -1 -1  0 |

Ответ 1

Я обнаружил, что проблема заключается в том, как я ищу минимальное время запуска в машинах для запуска задачи:

....

// Find the minimum time in all machines to start a task
b[3] = b[0]; // this cause the problem
for(count = 0; count < 3; ++count)
{
    if(b[count].t != 0)
        if(b[3].t > b[count + 1].t)
        {
            b[3] = b[count + 1];
        }
}

b[3], поскольку начало может ссылаться на машину, которая не может запустить текущую задачу, поэтому я сделал небольшое изменение:

// Find the minimum time in all machines to start a task
            for(count = 0; count < 3; ++count)  // search only in the machines that can execute the current task
            {
                if(b[count].m != -1)
                {
                    b[3] = b[count];
                    break;
                }
            }

            for(count = 0; count < 3; ++count)  // search for the first machines that can execute the current task
            {
                if(b[count].m != -1)
                {
                    if((b[3].t > b[count + 1].t) && (b[count + 1].m != -1)) // make sure the next machine can start the current task
                    {
                        b[3] = b[count + 1];
                    }
                }
            }

Полный алгоритм:

#include <stdio.h>

typedef struct _z_indispo {
    int t1;
    int t2;
} z_indispo; 

typedef struct _machines {
    int t[20]; // array represent time
    z_indispo zone[2];
} machines;

typedef struct _tache {
    int p;
    int w;
    int c; //  p/w
    int i; // Task number
} tache;

typedef struct _bfeet {
    int t; // Store the time to of ending execution by a task
    int m; // The machine responsible for executing a task.
} bfeet;

int main(int argc, char **argv)
{
    machines m[4] = {0};
    tache j[6];
    tache j_tmp;
    bfeet b[4] = {0};
    int i = 0;
    int n = 0;
    int u = 0;
    int k = 0;
    int count = 0;
    int trouver = 0;
    int f_totale = 0;
    int f[3] = {0};

    m[0].zone[0].t1 = 7;
    m[0].zone[0].t2 = 9;
    m[0].zone[1].t1 = 14;
    m[0].zone[1].t2 = 15;

    m[1].zone[0].t1 = 8;
    m[1].zone[0].t2 = 9;
    m[1].zone[1].t1 = 16;
    m[1].zone[1].t2 = 17;

    m[2].zone[0].t1 = 7;
    m[2].zone[0].t2 = 8;
    m[2].zone[1].t1 = 18;
    m[2].zone[1].t2 = 19;

    /*
     * Initialise all machines
     *   0: Represent free time.
     *  -1: Represent critical zone range.
     *  -2: Represent a task already executed. 
     */
    for(i = 0; i< 3; ++i)
    {
        for(count = 0; count < 20; ++count)
        {
            if((count >= m[i].zone[0].t1 - 1 && count <= m[i].zone[0].t2 - 1) || 
               (count >= m[i].zone[1].t1 - 1 && count <= m[i].zone[1].t2 - 1))
            {
                m[i].t[count] = -1;
            }
            else
            {
                m[i].t[count] = 0;
            }
        }
    }

    for(i = 0; i< 3; ++i)
    {
        if(i == 0)
            printf("   D(1,1)           t1    s1  D(1,2)     t2 s2  D(1,3)\n");
        else if(i == 1)
            printf("   D(2,1)              t1 s1  D(2,2)           t2 s2  D(2,3)\n");
        else if(i == 2)
            printf("   D(3,1)           t1 s1  D(3,2)                    t2 s2  D(3,3)\n");
        printf("|");
        for(count = 0; count < 20; ++count)
        {
                printf("%3d", m[i].t[count]);

        }

        printf(" |\n\n");
    }

    j[0].p = 5;
    j[0].w = 2;
    j[0].i = 1;

    j[1].p = 7;
    j[1].w = 3;
    j[1].i = 2;

    j[2].p = 4;
    j[2].w = 1;
    j[2].i = 3;

    j[3].p = 6;
    j[3].w = 4;
    j[3].i = 4;

    j[4].p = 7;
    j[4].w = 7;
    j[4].i = 5;

    /*
     * Calc C = P/W .
    */
    for(count = 0; count < 5; ++count)
    {
        j[count].c = j[count].p / j[count].w;
    }

    /*
     * Sort tasks from low to hight
     */
    for(count = 0; count < 5; ++count)
    {
        for(k = 0; k < 5 - count; ++k)
        {
            if(j[k].c > j[k + 1].c)
            {
                j_tmp = j[k + 1];
                j[k + 1] = j[k];
                j[k] = j_tmp;
            }
        }
    }


    printf("|%2J  |%2   P  |%2  W  | C  |\n");
    printf("_____________________\n");
    for(count = 0; count < 5; ++count)
    {
        printf("|%-4d|%-4d|%-4d|%-4d|\n", j[count].i, j[count].p, j[count].w, j[count].c);
    }

    printf("\n");

    /*
     * Execute tasks
     */
    while(n < 5) 
    {
        k = 0;
        for(count = 0; count < 3; ++count)
        {
            i = 0;
            u = 0;
            trouver = 0;
            while(i < 20 && trouver != 1)
            {
                if(m[count].t[i] == 0) // we find a free unite
                {
                    while(m[count].t[i] == 0 && u != j[n].p && i < 20) // count a continues free  time, quit when u equal the necessary time to execute the current task
                    {
                        ++u;
                        ++i;
                    }

                    if(u == j[n].p) // we found a free continues time
                    {
                        b[count].t = i - u; // save the starting index
                        b[count].m = count; // save the machine responsible for executing the current task
                        ++k;
                        trouver = 1;
                    }
                    else if(u != j[n].p) // if we encounter zone unavailability or index reserved by another task
                    {
                        u = 0; // restart u counter
                        while((m[count].t[i] == -1 || m[count].t[i] == -2) && (i < 20)) // bypass reserved/unavailability index's
                            ++i;
                    }
                }
                else
                    ++i; // bypass reserved/unavailability index's
            }

            if(trouver != 1) // we mark this machine as it can't execute the current task
            {
                b[count].m = -1;
            }
        }

        if(k == 0)
            printf("There is no free time to execute task %d.\n", j[n].i);
        else
        {
            // Find the minimum time in all machines to start a task
            for(count = 0; count < 3; ++count)  // search only in the machines that can execute the current task
            {
                if(b[count].m != -1)
                {
                    b[3] = b[count];
                    break;
                }
            }

            for(count = 0; count < 3; ++count)  // search only in the machines that can execute the current task
            {
                if(b[count].m != -1)
                {
                    if((b[3].t > b[count + 1].t) && (b[count + 1].m != -1))
                    {
                        b[3] = b[count + 1];
                    }
                }
            }

            // Put -2 to indicate that index as unfree
            u = b[3].t + j[n].p;
            for(count = b[3].t; count < u; ++count)
            {
                m[b[3].m].t[count] = -2;
            }

            if(b[3].m == 0)
                f[0] = f[0] + (b[3].t + j[n].p) * j[n].w;
            else if(b[3].m == 1)
                f[1] = f[1] + (b[3].t + j[n].p) * j[n].w;
            else if(b[3].m == 2)
                f[2] = f[2] + (b[3].t + j[n].p) * j[n].w;

            printf("Task %d end at %-3dms, machine %d.\n", j[n].i, b[3].t + j[n].p, b[3].m + 1);
        }
        ++n;
    }  

    printf("\n"); 
    f_totale = f[0] + f[1] + f[2];
    printf("F of machine 01: %d.\n", f[0]); 
    printf("F of machine 02: %d.\n", f[1]); 
    printf("F of machine 03: %d.\n", f[2]); 
    printf("Total F: %d.\n", f_totale); 
    printf("\n"); 
    printf("\n"); 
    for(i = 0; i< 3; ++i)
    {
        if(i == 0)
            printf("   D(1,1)           t1    s1  D(1,2)     t2 s2  D(1,3)\n");
        else if(i == 1)
            printf("   D(2,1)              t1 s1  D(2,2)           t2 s2  D(2,3)\n");
        else if(i == 2)
            printf("   D(3,1)           t1 s1  D(3,2)                    t2 s2  D(3,3)\n");
        printf("|");
        for(count = 0; count < 20; ++count)
        {
                printf("%3d", m[i].t[count]);

        }

        printf(" |\n\n");
    }

    return 0;
}

Ответ 2

У вас есть постоянные ошибки в определении массива. В основном, массивы C индексируются с нулевой отметкой, поэтому, если вы хотите получить доступ к array[n], array должен быть определен с размером не менее n+1. Например, ваша машинная структура должна быть

typedef struct _machines {
    int t[20];
    z_indispo zone[2];
} machines;

так как вы получаете доступ к machine.t[20] и machine.zone[1].

Это исправляет проблему в вашем втором обновлении (память, которая попадает на нее, это довольно хороший индикатор, который вы индексируете за пределами массива). Первый, скорее всего, будет исправлен (или, по крайней мере, вы будете намного дальше по пути к решению), как только вы исправите инициализацию массива в main() аналогичным образом (например, вы обращаетесь к b[3].t, но поскольку вы определили он через bfeet b[3] имеет только индексы b[0], b[1] и b[2]).