Я потратил на эту проблему несколько часов, она довольно проста, но быстро вышла из-под контроля.

Поскольку это довольно запутанно, я опубликую то, что я хочу, чтобы он делал, и что он на самом деле делает.

Цель

Если супервизор занят, он перейдет к следующему, если все они заняты, отобразится сообщение «Извините, все супервизоры заняты». То же и со всеми сотрудниками.

Метод

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

Затем он считывает, обладает ли сотрудник соответствующими навыками и был ли успех уже достигнут, чтобы одному и тому же человеку не была назначена одна и та же работа.

Если до сих пор все в порядке, он проверяет, занят ли супервизор, если да, то возвращается и меняет супервизора.

Затем он назначает информацию сотруднику, также назначает некоторые данные руководителю и проверяет условие «успеха».

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

После всего этого программа назначает работу, пока она работает в разумной степени, но я хочу, чтобы было сообщение о том, что если все супервизоры заняты, работа больше не может быть распределена.

Раньше я использовал MessageBox.Show после операторов foreach, но если один супервизор занят, он будет отображать сообщение, которое мне не нужно.

Код

Метод распределения работы

bool finishLast = false;
bool successFirst = false;
while (successFirst != true)
{
    foreach (Supervisor sup in supervisors)
    {
        bool failure = false;
        while (failure != true)
        {
            foreach (Employee emp in employees)
            {
                if (emp.Busy == false && emp.Skills.HasFlag(_skillRequired) && successFirst == false)
                {
                    if (sup.SupervisorOccupied == false)
                    {
                        successFirst = true;
                        emp.EmployeeWorkload = _jobName;
                        emp.ShiftsLeft = _shiftsLeft;
                        emp.Busy = true;
                        sup.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
                        sup.ShiftsLeft = _shiftsLeft;
                        sup.SupervisorOccupied = true;
                    }
                }
                else if (emp.Busy == true)
                {
                    failure = true;
                }
            }
        }
        if (failure == true)
        {
            finishLast = true;
        }
    }
    if (finishLast == true)
    {
        successFirst = true;
    }
}

Конечно, если кто-то может придумать более простой способ получить это, я буду открыт для идей.

ИЗМЕНИТЬ 1

Это не многопоточная система, да, emp.Busy и sup.SupervisorOccupied технически одно и то же, они оба находятся в same class, так что да, sup может наследовать emp.Busy.

3
Danny Watson 23 Дек 2015 в 17:22

2 ответа

Лучший ответ

Думаю, должно работать что-то вроде этого:

        bool assigned = false;
        foreach (Supervisor sup in supervisors)
        {
            if (!sup.SupervisorOccupied)
            {
                foreach (Employee emp in employees)
                {
                    if (!emp.Busy && emp.Skills.HasFlag(_skillRequired))
                    {
                        assigned = true;
                        emp.EmployeeWorkload = _jobName;
                        emp.ShiftsLeft = _shiftsLeft;
                        emp.Busy = true;
                        sup.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
                        sup.ShiftsLeft = _shiftsLeft;
                        sup.SupervisorOccupied = true;
                        break;
                    }
                }
            }
            if (assigned)
                break;
        }

Если в конце «назначено == ложь», сотрудник недоступен (на самом деле отсутствует какой-то код, поэтому он не может работать, но теоретически он должен делать то, что вы хотите!).

5
Leonardo Spina 23 Дек 2015 в 14:39

Вот как вы должны написать этот код:

var availableSupervisor = supervisors
    .FirstOrDefault(supervisor => !supervisor.SupervisorOccupied);
if (availableSupervisor == null)
    return;

var availableEmployee = employees
    .FirstOrDefault(employee => !employee.Busy && employee.Skills.HasFlag(_skillRequired));
if (availableEmployee == null)
    return;

availableEmployee.EmployeeWorkload = _jobName;
availableEmployee.ShiftsLeft = _shiftsLeft;
availableEmployee.Busy = true;
availableSupervisor.EmployeeWorkload = "Supervising Employee: " + emp.EmployeeName + " to finish task: " + emp.EmployeeWorkload;
availableSupervisor.ShiftsLeft = _shiftsLeft;
availableSupervisor.SupervisorOccupied = true;
3
Lasse V. Karlsen 23 Дек 2015 в 18:43