Anylogic переменная не обновляется - PullRequest
0 голосов
/ 15 апреля 2019

Я использую симулятор дискретных событий в AnyLogic.У меня возникла проблема с некоторым кодом, который обновляет переменную в моем моделировании.Я храню дату и время, когда агент покидает исходный блок, и дату, когда он входит в блок приемника.Я пытаюсь записать количество «нарушений правил» для всех агентов.Разрыв правила определен ниже (два способа нарушения):

1) Если агент получен раньше определенного времени (называемый SDC), и агент не завершен к 17:00 того же дня, агент имеетнарушил правило

2) Если агент не завершен к следующему дню в определенное время (называемое НДЦ), то агент нарушил правило

Я записываю ноль или единицудля каждого агента, если они нарушают любое правило в переменной с именем RuleBreak.Однако в моих прогонах симуляции переменная вообще не обновляется.Я надеюсь, что я просто пропускаю что-то маленькое.Буду признателен за любую помощь!(код ниже)

Calendar received = Calendar.getInstance();
received.setTime(ReceivedDate);

Calendar completion = Calendar.getInstance();
completion.setTime(Completion);

Calendar SD_at_5 = Calendar.getInstance();
SD_at_5.setTime(ReceivedDate);
SD_at_5.set(Calendar.HOUR_OF_DAY,17);
SD_at_5.set(Calendar.MINUTE, 0);
SD_at_5.set(Calendar.SECOND, 0);

Calendar Tomorrow_at_NDC = Calendar.getInstance();
Tomorrow_at_NDC.setTime(ReceivedDate);
if(Tomorrow_at_NDC.get(Calendar.DAY_OF_WEEK) == 6)
    Tomorrow_at_NDC.add(Calendar.DATE, 3);
else 
    Tomorrow_at_NDC.add(Calendar.DATE, 1);
Tomorrow_at_NDC.add(Calendar.DATE, 1);
Tomorrow_at_NDC.set(Calendar.HOUR_OF_DAY,NDC);
Tomorrow_at_NDC.set(Calendar.MINUTE, 0);
Tomorrow_at_NDC.set(Calendar.SECOND, 0);

int Either_rule_break = 0;
double time_diff_SDC = differenceInCalendarUnits(TimeUnits.SECOND,completion.getTime(),SD_at_5.getTime());
double time_diff_NDC = differenceInCalendarUnits(TimeUnits.SECOND,completion.getTime(),Tomorrow_at_NDC.getTime());

if((received.get(Calendar.HOUR_OF_DAY) < SDC) && (time_diff_SDC <= 0))  
    Either_rule_break = Either_rule_break + 1;
else
   Either_rule_break = Either_rule_break + 0;

if((received.get(Calendar.HOUR_OF_DAY) >= SDC) && (time_diff_NDC <= 0))
    Either_rule_break = Either_rule_break + 1;
else
    Either_rule_break = Either_rule_break + 0;

if((Either_rule_break >= 1))
    RuleBreak = RuleBreak + 1;
else 
    RuleBreak = RuleBreak + 0;

1 Ответ

0 голосов
/ 16 апреля 2019

Вы действительно не объяснили, где этот код используется и что он получает.Я предполагаю, что код находится в функции, вызываемой в действии приемника при приеме, где ReceivedDate и Completion - это Date экземпляров, сохраняемых для каждого агента (время выхода из источника и время входа в приемник, как даты, записанные с помощью AnyLogic date() function).

И похоже, что ваш день SDC хранится в SDC, а ваш час-день NDC в NDCRuleBreak в качестве переменной в Main или аналогичное, сохраняющее общее количество нарушений правил).

Ваши вычисления выглядят хорошо, за исключением того, что календарный расчет Tomorrow_at_NDC кажется неправильным: вы добавляете 1 день дважды (если не суббота) или 3 дня плюс 1 день(если суббота; в календаре Java днем ​​недели 1 является понедельник).

(Ваша Java также очень «неэффективна» с ненужными дополнительными локальными переменными и выполнением логики, когда вам это не нужно;например, нет смысла делать всю подготовку к календарю и проверить на наличие нарушения правил типа 1, если время приема прошло после часа SDC.)

Но вы уверены, что есть любое правило-перерывы;как вы настроили свою модель, чтобы убедиться, что есть (для проверки)?Кроме того, RuleBreak определенно является переменной вне агентов, которые проходят через ваш DES (то есть, в Main или аналогичном)?Кроме того, Completion и ReceivedDate определенно хранятся на агента , поэтому, например, если бы ваша функция называлась checkForRuleBreaks, вы бы выполняли что-то похожее на приведенное ниже в своем действии при выходе из раковины:

agent.Completion = date();   // Agent received date set earlier in Source action
checkForRuleBreaks(agent.ReceivedDate, agent.Completion);

(На самом деле вам вообще не нужно хранить дату завершения в агенте, поскольку она всегда будет текущей сим-датой внутри вашей функции, и вы можете просто вычислить ее там.)

...