Я новичок в Dymola, и мне не удается запустить этот код. Я пытаюсь создать случайное поколение, чтобы имитировать количество людей в комнате.
Вот код, который у меня есть на данный момент. Есть ли у вас идеи, в чем может быть проблема?
model Trial
Real p(start=rand()/32767);
Real E(start=1);
equation
when (sample(1,3600)) then//sample(start+interval) ce qui donne "start + i*interval"
p = rand()/32767;
if E == 1 then
if p < 0.2 then
E = 2;
elseif p < 0.6 then
E = 3;
else
E = 4;
end if;
elseif E == 2 then
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 3;
else
E = 4;
end if;
elseif E == 3 then
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 2;
else
E = 4;
end if;
elseif E == 4 then
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 2;
else
E = 3;
end if;
end if;
end when;
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)),
experiment(StopTime=86400, __Dymola_Algorithm = "Dassl"));
end Trial;
Есть ряд проблем. Сначала исправленный код:
model Trial
impure function rand
output Integer i;
external "C";
end rand;
Real p(start=rand()/32767);
Integer E(start=1);
equation
when (sample(1,3600)) then//sample(start+interval) ce qui donne "start + i*interval"
p = rand()/32767;
if pre(E) == 1 then
if p < 0.2 then
E = 2;
elseif p < 0.6 then
E = 3;
else
E = 4;
end if;
elseif pre(E) == 2 then
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 3;
else
E = 4;
end if;
elseif pre(E) == 3 then
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 2;
else
E = 4;
end if;
else
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 2;
else
E = 3;
end if;
end if;
end when;
annotation (Icon(coordinateSystem(preserveAspectRatio=false)), Diagram(
coordinateSystem(preserveAspectRatio=false)),
experiment(StopTime=86400, __Dymola_Algorithm = "Dassl"));
end Trial;
Далее список изменений:
E
— целое число, а не действительное число, что также позволяет сравнивать.pre(E)
для доступа к предыдущему значению E.impure
.Предлагаю вам посмотреть Modelica.Math.Random.Examples.GenerateRandomNumbers
. На основе этого примера у меня получилось:
model Trial
parameter Integer id=Modelica.Math.Random.Utilities.initializeImpureRandom(globalSeed) "A unique number used to sort equations correctly";
parameter Integer globalSeed=30020 "Global seed to initialize random number generator";
Real p(start=Modelica.Math.Random.Utilities.impureRandom(id=id));
Integer E(start=1, fixed=true);
equation
when (sample(1, 3600)) then
//sample(start+interval) ce qui donne "start + i*interval"
p = Modelica.Math.Random.Utilities.impureRandom(id=id);
if pre(E) == 1 then
if p < 0.2 then
E = 2;
elseif p < 0.6 then
E = 3;
else
E = 4;
end if;
elseif pre(E) == 2 then
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 3;
else
E = 4;
end if;
elseif pre(E) == 3 then
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 2;
else
E = 4;
end if;
else
// if E == 4
if p < 0.2 then
E = 1;
elseif p < 0.6 then
E = 2;
else
E = 3;
end if;
end if;
end when;
annotation (
Icon(coordinateSystem(preserveAspectRatio=false)),
Diagram(coordinateSystem(preserveAspectRatio=false)),
experiment(StopTime=86400, __Dymola_Algorithm = "Dassl"));
end Trial;
Я еще поправил:
E
: Real to Integer + fixed=true
,E
: pre(E) позволяет избежать алгебраического цикла,else
.