Home
/
Blog
/
INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS EN SIMULA: PARTE 2
or select a category:
All posts
INTRODUCCIÓN A LA PROGRAMACIÓN

INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS EN SIMULA: PARTE 2

This article has been translated into Spanish. You can find the original version at the following link.

Las listas anteriores están representadas por tres clases, consulta la Figura 7. Linkage es un conocimiento sobre el enlace bidireccional en sí. Esto se especializa aún más como encabezado y elementos miembros.

Figura 7: Clases declaradas en la clase del sistema Simset.

Métodos de las clases relacionadas con las listas:

Linkage

  • Suc es el sucesor calificado para Link (None para el último elemento de la lista).
  • Pred es el predecesor calificado para Link (None para el primer elemento de la lista).
  • Prev es el elemento anterior calificado para Linkage.

Head

  • First es el primer elemento de la lista (None si la lista está vacía).
  • Last es el último elemento de la lista (None si la lista está vacía).
  • Empty devuelve verdadero si la lista está vacía.
  • Cardinal es el número de elementos en la lista.
  • Clear elimina todos los elementos de la lista; la memoria se recuperará mediante el recolector de basura.

Link

  • Into(S) inserta el elemento al final de la lista (Head) S.
  • Out elimina el elemento de la lista.
  • Follow(L) inserta el elemento que realiza este método después del Linkage L.
  • Precede(L) inserta el elemento que realiza este método antes del Linkage L.

Los métodos se pueden combinar para representar actividades complejas. Por ejemplo, la instrucción de procedimiento:

Queue1.Last.Precede(Queue2.First);

quita el último elemento de Queue1 e lo inserta al principio de Queue2.

SIMULA SISTEMAS CUASIPARALELOS

Las reglas de vida de los objetos Simula son corutinas, que pueden detenerse temporalmente y luego reanudarse. Hay dos niveles de (cuasi)paralelismo en Simula. El primer nivel no trabaja con el tiempo; el programador "piensa en cuasiparalelo". El segundo nivel introduce la noción de tiempo; el programador trabaja con procesos paralelos (desde el punto de vista del usuario). El primer nivel se puede aplicar a todas las clases; el segundo nivel está implementado por la clase Process de la clase del sistema Simulation. La Figura 8 muestra los posibles estados de una corutina (cuerpo) de un objeto X. Observa que una corutina que no utiliza ninguna de las instalaciones siguientes primero está adjunta y luego se termina (los objetos de otros OOL siempre se terminan). Un objeto terminado aún se puede usar (es posible llamar a sus métodos y/o acceder a sus atributos). Estas son las instalaciones de Simula (métodos disponibles en todas las clases) que admiten el trabajo con sistemas cuasiparalelos (QPS):

  • Detach detiene la ejecución del objeto actual (el que realiza Detach). El objeto actual se vuelve desvinculado. El control se pasa al punto donde se creó o reanudó el objeto actual.
  • Resume(Y) activa un objeto Y desvinculado que se reanuda. El objeto actual se vuelve desvinculado.
  • Call(Y) es similar a Resume, pero el objeto Y se vincula al objeto actual. El objeto actual se vuelve desvinculado. El objeto actual se reanudará después de desvincular Y.

Figura 8: Diagrama de estados de las corutinas en Simula.

Ejemplo 1 de QPS: Control de un juego de ajedrez usando el enfoque de Dos Maestros.

En el siguiente programa hay tres corutinas: los dos jugadores y el bloque principal. Ten en cuenta que los dos primeros movimientos son especiales. Un jugador puede ganar con cierta probabilidad a partir del tercer movimiento en adelante: Draw(0.3,Seed) es una función booleana que devuelve true con una probabilidad del 0.3. Observa cómo el bloque principal crea a los dos jugadores, los enlaza mediante los atributos Opponent y pasa el control al Blanco. Luego, los jugadores realizan repetidamente sus movimientos y reanudan al oponente hasta que uno de ellos gana. Esto termina sus cuerpos y el control se pasa al bloque principal.

Begin

   Boolean Mate;

   Ref(Player) White, Black, Winner;

   Integer Seed; 

   Class Player(PName); Text PName;

   Begin

  Ref(Player) Opponent;

  Integer Move;

       ! The life follows;

   Detach;

   OutText(PName); OutText("'s First Move"); OutImage;

   Resume(Opponent);

   OutText(PName); OutText("'s Second Move"); OutImage;

   Resume(Opponent);

   Move := 2;

   While not Mate do begin

      Move := Move+1;

    OutText(PName); OutText("'s Move # ");

      OutInt(Move,3); OutImage;

      If Draw(0.3,Seed) then begin

         Mate := true; Winner :- This Player;

      End If;

      Resume(Opponent);

   End While;

   End of Player;

   Begin   ! QPS head;

   OutText("Creating Players, Starting the white one"); OutImage;

   White :- New Player("White");

   Black :- New Player("Black");

   White.Opponent :- Black;

   Black.Opponent :- White;

   Seed := 17;

   Resume(White);

     OutText("Finish: "); OutText(Winner.PName);

   OutText(" won in move"); OutInt(Winner.Move,3); OutImage;

   End of QPS

End of program;

Este es el resultado con sangría del programa anterior. La sangría muestra el objeto que genera la salida, desde la izquierda: Main block, White, Black.

Creando jugadores, comenzando con el blanco

Primer movimiento de Blanco

Primer movimiento de Negro

Segundo movimiento de Blanco

Segundo movimiento de Negro

Movimiento # 3 de Blanco

Movimiento # 3 de Negro

Movimiento # 4 de Blanco

Movimiento # 4 de Negro

Fin: Negro ganó en el movimiento 4

QPS Ejemplo 2: Control del juego de ajedrez utilizando el enfoque de Maestro y Dos Esclavos.

En el siguiente programa también hay tres corotinas: los dos jugadores y el bloque principal. La diferencia entre este y el programa anterior es el papel activo del bloque principal. Los jugadores no se reanudan entre sí. Simplemente hacen el movimiento y se desvinculan. El bloque principal los activa repetidamente hasta que uno de ellos gana. Observa el uso de Call: los jugadores se adjuntan repetidamente al bloque principal.

Begin

   Boolean Mate;

   Ref(Player) White,Black,Winner;

   Integer Seed;

   Class Player(PName); Text PName;

   Begin

  Ref(Player) Opponent;

  Integer Move;

  ! The life follows;

   Detach;

   OutText(PName); OutText("'s First Move"); OutImage;

   Detach;

   OutText(PName); OutText("'s Second Move"); OutImage;

   Detach;

   Move := 2;

      While true do begin

      Move := Move+1;

      OutText(PName); OutText("'s Move # ");

      OutInt(Move,3); OutImage;

      If Draw(0.05,Seed) then begin

         Mate := true; Winner :- This Player;

      end;

      Detach;

  End While;

   End Player; 

   Begin

   OutText("Creating Players, Starting the game"); OutImage;

   White :- New Player("White");

   Black :- New Player("Black");

   White.Opponent :- Black;

   Black.Opponent :- White;

   Seed := 11;

      While not Mate do begin

      Call(White);

      If not Mate then Call(Black)

   End While;

   OutText("Finish: "); OutText(Winner.PName);

   OutText(" won in move"); OutInt(Winner.Move,3); OutImage;

   End

End;

Este es el resultado con sangría del programa anterior. La sangría muestra el objeto que genera la salida, desde la izquierda: Main block, White, Black.

Creating Players, Starting the game

Primer movimiento de Blanco

Primer movimiento de Negro

Segundo movimiento de Blanco

Segundo movimiento de Negro

Movimiento # 3 de Blanco

Movimiento # 3 de Negro

Movimiento # 4 de Blanco

Movimiento # 4 de Negro

Movimiento # 5 de Blanco

Movimiento # 5 de Negro

Movimiento # 6 de Blanco

Fin: Blanco ganó en el movimiento 6

QPS Ejemplo 3: Control del juego de ajedrez utilizando el enfoque de Maestro y Dos Esclavos implementado como un paquete (clase principal).

En el siguiente programa, la clase principal Chess declara dos clases locales: Player y Referee. Las reglas de vida de la clase principal preparan el juego creando y vinculando a los dos jugadores y al árbitro. Los tres objetos se desvinculan y el cuerpo de la clase principal termina. El juego debe ser iniciado por el programa (un bloque precedido por Chess). El prefijo importa todas las declaraciones y prepara el juego. Ten en cuenta que el bloque precedido simplemente activa al árbitro y evalúa el juego.

Class Chess; ! Main class with local: Player, Referee;

   Begin

   Boolean Mate;

   Ref(Player) White,Black,Winner;

   Ref(Referee) Master;

   Integer Seed; 

   Class Player(PName); Text PName;

   Begin

  Ref(Player) Opponent;

  Integer Move;

             ! The life of Player;

   Detach;

   OutText(PName); OutText("'s First Move"); OutImage;

   Detach;

   OutText(PName); OutText("'s Second Move"); OutImage;

   Detach;

   Move := 2;

   While true do begin

      Move := Move+1;

      OutText(PName); OutText("'s Move # ");

      OutInt(Move,3); OutImage;

      If Draw(0.05,Seed) then begin

         Mate := true; Winner :- This Player;

      end;

      Detach;

   End While;

   End Player; 

   Class Referee;

   Begin

   Detach;

   While not Mate do begin

      Call(White);

      If not Mate then Call(Black)

   End While

   End of Referee; 

   Begin ! Life of Chess;

   Seed := 11;

   OutText("Creating the Players and the Master"); OutImage;

   White :- New Player("White");

   Black :- New Player("Black");

   White.Opponent :- Black;

   Black.Opponent :- White;

   Master :- New Referee;

   End

End of Chess;

El siguiente programa utiliza la clase principal Chess:

External Class Chess; 

Chess Begin

OutText("Resuming the Master"); OutImage;

Resume(Master);

OutText("Finish: "); OutText(Winner.PName);

OutText(" won in move"); OutInt(Winner.Move,3); OutImage;

End of Program;

Este es el resultado con sangría del programa anterior. La sangría muestra el objeto que genera la salida, desde la izquierda: Body of Chess, Prefixed block, White, Black.

Crear jugadores, iniciar el jugador blanco

Primer movimiento de Blanco

Primer movimiento de Negro

Segundo movimiento de Blanco

Segundo movimiento de Negro

Movimiento # 3 de Blanco

Movimiento # 3 de Negro

Movimiento # 4 de Blanco

Movimiento # 4 de Negro

Fin: Negro ganó en el movimiento 4

SIMULACIÓN = MUNDO DE PROCESOS PARALELOS

La noción básica de la clase del sistema Simulación es el Process (Proceso,) una secuencia de eventos instantáneos (representados por segmentos de código) separados por períodos pasivos. La Figura 9 muestra las clases declaradas en Simulación y sus métodos. Event Notice (un subtipo de Link) representa un evento programado que ocurrirá en un momento específico, EvTime, en el futuro. Proc es el proceso cuyo segmento de código se activará. SQS (un subtipo de Head) es una lista de eventos ordenados por tiempo. Es la Agenda habitual de los lenguajes de simulación discreta. Conceptualmente, es una lista vinculada ordenada, la implementación interna se basa típicamente en una estructura de árbol más eficiente. Obviamente, esta lista no se puede acceder directamente desde el programa del usuario. Hay instalaciones de programación: consulte más adelante, que admiten el trabajo con el tiempo y la sincronización mutua de procesos. Los procesos del programa del usuario son subclases del ancestro común Proceso. Los dos primeros métodos prueban su estado, los otros dos devuelven el próximo evento programado y su tiempo de activación.

Figura 9: Clases de la clase de sistema Simulación.

Las facilidades de la clase de sistema Simulación están implementadas por los métodos "de bajo nivel" cuasiparalelos: detach, resume, call, pero son más fáciles de usar. Un usuario de Simulación "piensa en paralelo". La dinámica de un modelo de simulación se expresa en términos de procesos paralelos que interactúan mutuamente. Esta forma es muy natural; es exactamente cómo funciona el mundo real.

Keen Writer
4.8 (104 reviews)
Degree:
Bachelor
Total orders:
1584
Ready to elevate your essay game? Let our experts do the heavy lifting!
Get expert help now

Estados de un objeto de proceso:

  • Active (Activo): un segmento del proceso se está ejecutando.
  • Suspended (Suspendido): el proceso tiene su aviso de evento en SQS. A menos que se cancele, se activará en el futuro.
  • Passive (Pasivo): el proceso no tiene ningún evento programado. Debe ser activado por otro proceso.
  • Terminated (Terminado): el proceso ha terminado. No se puede activar nuevamente.

Facilidades de temporización, secuenciación y sincronización:

  • Activate X (Activar X) activa un proceso pasivo X.
  • Reactivate X (Reactivar X): o bien activa un proceso pasivo o cambia el próximo tiempo de activación si el proceso está suspendido o activo.
  • Hold(T) genera el retraso T en la vida del proceso.
  • Passivate (Pasivar): hace que el proceso actual sea pasivo.
  • Cancel(X): cancela la próxima activación de X.
  • Wait(Q): pasa el proceso a estado pasivo y lo coloca al final de la lista (cola) Q.

Ejemplo de Simulación 1: Un sistema de colas multicanal - Enfoque de Cliente Activo.

La Figura 10 muestra el sistema que se está simulando. Es una abstracción de, por ejemplo, un banco donde los clientes esperan en una cola para cualquiera de los cajeros. El intervalo entre llegadas es aleatorio, distribuido uniformemente entre 1 y 3 minutos. Todos los servidores tienen el mismo tiempo de servicio aleatorio, que se distribuye normalmente con un valor medio de 8 minutos y una desviación estándar de 2 minutos. La simulación debería encontrar el tiempo promedio que un cliente pasa en el sistema. (Ten en cuenta que no está disponible un modelo analítico del sistema mencionado). La simulación de sistemas similares en Simula (exactamente en la clase de sistema Simulation de Simula) siempre comienza identificando procesos. Un proceso es, obviamente, el generador de clientes: generará repetidamente un cliente, registrará su tiempo de llegada y esperará un retraso aleatorio. Para expresar la dinámica del sistema, hay dos enfoques lógicos. El primero (utilizado en este ejemplo) se basa en clientes activos y servidores pasivos. El enfoque opuesto: servidores activos, clientes pasivos, se muestra en el siguiente ejemplo. Un cliente activo tiene reglas de vida representadas por los siguientes pasos:

  1. Si hay un servidor libre, procede. Espera en la cola en caso contrario.
  2. Ocupa un servidor, genera un retraso aleatorio que representa el tiempo de servicio.
  3. Libera el servidor.
  4. Si hay un cliente esperando (si la cola no está vacía), retíralo de la cola y actívalo. (El cliente activado iniciará su paso 2).
  5. Actualiza las estadísticas.

Figura 10: Diagrama del sistema para un sistema de colas multicanal.

El siguiente programa es un modelo de simulación del sistema mencionado anteriormente. Ten en cuenta que el objetivo principal era mostrar la lógica del modelo en un programa lo más simple posible. Los modelos de simulación reales, por supuesto, solicitan todos los parámetros variables y proporcionan más resultados (como, por ejemplo, la longitud promedio y máxima de la cola, etc.). En el siguiente programa hay dos procesos que existen durante todo el experimento: el generador y el programa principal (bloque precedido por Simulation), que simplemente espera hasta que termine el experimento y luego muestra el resultado. Luego hay una cantidad variable de procesos de clientes, que existen temporalmente. Después de actualizar las estadísticas, los clientes terminan. Observa el uso de funciones estándar para generar retrasos aleatorios. Hay funciones estándar en Simula para la mayoría de las distribuciones comúnmente utilizadas. Todas reciben una variable entera como semilla para ser utilizada por el generador de números aleatorios. Entonces, todos los valores aleatorios pueden usar flujos separados de números aleatorios o compartir uno común.

! Active customer approach;

Simulation Begin

  Real  TrialDuration; ! Experiment length [min];

  Ref(Head)  Queue;   ! The queue;

  Integer  Servers;   ! Total number of servers;

  Integer  BusyServers;   ! Numbers of working servers;

  Integer  TrialSeedG, TrialSeedS; ! Seeds of random generators;

  Long Real  TotalTime, TimeSpent; ! Variables for statistics;

  Integer  CustomersOut;  ! Number of served customers;

  Real  MinInt, MaxInt;   ! Uniform interval between arrivals;

  Real  SMean, SStd;  ! Normal service duration;

 

  Process Class Generator;

  Begin

While true do begin

   Activate New Customer(Time);  ! Time is the current (arrival) time;

   ! Interval between arrivals: ;

   Hold(Uniform(MinInt, MaxInt, TrialSeedG));

End While;

  End of Generator;

 

  Process Class Customer(Arrival);  Real Arrival;

  Begin

Ref(Customer)  Next;

 

If not Queue.Empty or (BusyServers >= Servers) then

Wait(Queue);     ! Customer has to wait in the Queue;

   ! Service can start: ;

BusyServers := BusyServers + 1;  ! Seize a server;

   ! This is the teller service: ;

Hold(Normal(SMean, SStd, TrialSeedS));

BusyServers := BusyServers - 1;  ! Release the server;

If not Queue.Empty then begin

   Next :- Queue.First;

   Next.Out;       ! First from Queue served;

   Activate Next after Current;

End If;

CustomersOut := CustomersOut + 1; ! Statistics;

TotalTime := TotalTime + (Time - Arrival);

  End of Customer;

 

! MAIN program body: ;

  TrialSeedG := 7;  TrialSeedS := 23;  ! Seeds for random variables;

  MinInt := 1; MaxInt := 3;        ! Min and Max intervals;

  SMean := 8; SStd  := 2;          ! Random normal servers;

  OutText("Enter the number of Servers : "); OutImage;

  Servers := InInt;                ! Initial numbers;

  TrialDuration := 600;            ! Other variables initialized to 0;

  Queue :- New Head;               ! Create an empty queue;

  Activate New Generator;          ! This starts the experiment;

  Hold(TrialDuration);             ! Experiment duration;

  TimeSpent := TotalTime/CustomersOut;

  OutText("Average time spent in the system: ");

  OutFix(TimeSpent, 3, 10); OutImage;

  InImage

End of program;

Ejemplo de Simulación 2: Un sistema de colas multicanal – Enfoque de Servidor Activo.

Este ejemplo simula el mismo sistema que en el ejemplo anterior; consulta la Figura 10. La diferencia radica en el servidor activo, que atiende repetidamente a los clientes en la cola hasta que la cola esté vacía. Luego, el servidor se pasa a pasivo. Al principio, los clientes activan todos los servidores inactivos (si los hay) y luego van a la cola. Esto, por supuesto, no es muy eficiente, pero es simple. Los clientes son activados por los servidores después de completar el servicio. En el resto de sus vidas, los clientes solo actualizan las estadísticas. El programa principal crea y activa todos los servidores, pero se desactivan de inmediato porque la cola está vacía. Luego, el programa principal activa el generador y espera hasta que termine el experimento.

! Active server approach;

Simulation Begin

  Real  TrialDuration;   ! Experiment length [min];

  Ref(Head)  Queue;      ! The queue;

  Integer  Servers;     ! Total number of servers;

  Integer  TrialSeedG, TrialSeedS; ! Seeds of random generators;

  Long Real  TotalTime, TimeSpent; ! Variables for statistics;

  Integer  CustomersOut; ! Number of served customers;

  Real  MinInt, MaxInt;  ! Uniform interval between arrivals;

  Real  SMean, SStd;     ! Normal service duration;

  Ref(Server) Array ServBank(1:10);   ! Max. number of servers is 10;

  Integer i;

 

  Process Class Generator;

  Begin

While true do begin

   Activate New Customer(Time);

    ! Interval between arrivals: ;

   Hold(Uniform(MinInt, MaxInt, TrialSeedG));

End While;

  End of Generator;

 

  Process Class Server;

  Begin

Ref(Customer) ServedOne;

 

While true do

   If not Queue.Empty then begin

     ServedOne :- Queue.First;

     ServedOne.Out;  ! First from Queue served;

     Hold(Normal(SMean, SStd, TrialSeedS));

     Activate ServedOne after Current

    end

   Else

     Passivate;

  End of Server;

 

  Process Class Customer(Arrival);  Real Arrival;

  Begin

For i:=1 step 1 until Servers do

   If ServBank(i).Idle then

     Activate ServBank(i) after Current;

Wait(Queue);

 

  ! Service finished: ;

CustomersOut := CustomersOut + 1;  ! Statistics;

TotalTime := TotalTime + Time - Arrival;

  End of Customer;

 

! MAIN program body: ;

  TrialSeedG := 7;  TrialSeedS := 23;  ! Seeds for random variables;

  MinInt := 1; MaxInt := 3;        ! Min and Max intervals;

  SMean := 8; SStd  := 2;          ! Random normal servers;

  OutText("Enter the number of Servers : "); OutImage;

  Servers := InInt;                ! Initial numbers;

  TrialDuration := 600;

  Queue :- New Head;

  For i:=1 step 1 until Servers do begin

ServBank(i) :- New Server;

   Activate ServBank(i)           ! Create and activate all servers;

  End For;

  Activate New Generator;          ! This starts the experiment;

  Hold(TrialDuration);             ! Experiment duration;

  TimeSpent := TotalTime / CustomersOut;

  OutText("Average time spent in the system: ");

  OutFix(TimeSpent, 3, 10); OutImage;

  InImage

End of program;

Get Help with Your Essay, Spend Your Time Wisely.
Get help!
Place My Order

SIMULA NESTED QPS

Un sistema cuasiparalelo (QPS) en Simula es básicamente un bloque (típicamente, pero no necesariamente, uno prefijado), cuyo cuerpo crea algunos objetos que, junto con el bloque principal, forman el sistema de corutinas cuasiparalelas. Debido a que Simula (a diferencia, por ejemplo, de Pascal) es un verdadero lenguaje orientado a bloques, el bloque (que generalmente significa un QPS) puede ocurrir en cualquier lugar del código como una instrucción. Esto significa que un QPS puede contener QPS locales (anidados), que también pueden contener QPS locales, etc. Esta regla simple proporciona una manera de crear estructuras increíblemente complejas con consecuencias que hasta ahora no se han utilizado completamente ni entendido. El siguiente programa esboza un posible uso de un QPS anidado en el control de ajedrez. El próximo capítulo muestra un programa de simulación con simulaciones anidadas.

Ejemplo de QPS anidado: un control de ajedrez que utiliza un juego simulado como parte de la decisión.

Supongamos que un jugador de ajedrez, como parte de su decisión, simula el juego actual para verificar el posible resultado del próximo movimiento. El siguiente programa (basado en el Enfoque de Dos Maestros) es un esbozo de una posible solución. Observa que la clase Player tiene un método TestStrategy llamado como parte de cada decisión. Este método implementa un QPS similar al externo. Contiene una clase local TestPlayer, que podría ser muy similar al Player externo, excepto TestStrategy (puede tener algo similar, pero la anidación debe detenerse en cierto nivel). El cuerpo de TestStrategy es el QPS interno cuyos resultados son utilizados por Player en el nivel superior.

Begin

  Boolean  Mate;

  Ref(Player)  White, Black, Winner;

  Integer  Seed;

 

  Class Player(PName);  Text PName;

  Begin

Ref(Player) Opponent;

Integer Move;

 

Procedure TestStrategy;

Begin

   Class TestPlayer ... ;

 

   Begin

     ! Internal experiment, similar to the outer QPS;

      ...

   End of internal QPS;

End of TestStrategy;

 

   ! The life of Player;

Detach;

TestStrategy;

OutText(PName);  OutText("'s First Move");  OutImage;

Resume(Opponent);

TestStrategy;

OutText(PName);  OutText("'s Second Move");  OutImage;

Resume(Opponent);

Move := 2;

While not Mate do begin

   Move := Move+1;

   TestStrategy;

   OutText(PName);  OutText("'s Move # ");

   OutInt(Move,3);  OutImage;

   If  Draw(0.3,Seed)  then  begin

     Mate := true;

     Winner :- This Player;

   End If;

   Resume(Opponent);

End While;

  End of Player;

 

  Begin   ! This block is the outer QPS head;

   OutText("Creating Players,  Starting the white one");  OutImage;

White :- New Player("White");

Black :- New Player("Black");

White.Opponent :- Black;

Black.Opponent :- White;

Seed := 17;

Resume(White);

OutText("Finish: ");  OutText(Winner.PName);

OutText(" won in move");  OutInt(Winner.Move,3);  OutImage;

  End of outer QPS;

End of program;

SIMULA SIMULACIÓN NESTED

Hay dos niveles de cuasiparalelismo en Simula, ambos pueden implementar sistemas anidados. El capítulo anterior trata sobre QPS anidados de bajo nivel. La clase de sistema Simulation introduce la noción de tiempo. Esto significa que si está anidado, habrá otros tiempos locales (anidados). La idea básica se encuentra en la Figura 11. Las declaraciones Hold con demoras x y z se aplican al tiempo principal (externo). La declaración Hold con la demora y está en otro mundo alternativo. Así que en Simula es posible simular sistemas que hasta ahora solo se encuentran en la ciencia ficción. Hay aplicaciones prácticas. Básicamente, es posible simular sistemas que contienen la simulación como parte de la toma de decisiones. Considere esta situación: hay un cierto sistema complejo y un grupo de expertos que sugieren diferentes decisiones, cuyos resultados no se pueden probar de manera trivial o analítica. (¿No es este el caso usual en la práctica?) Para probar y evaluar sus propuestas de decisión, los expertos realizan experimentos de simulación, comparan los resultados y seleccionan la decisión más prometedora. Ahora supongamos que todo esto se simulará.

Figure 11: Basic ideas of Nested Simulation.

Ejemplo de Simulación Anidada: Una red de colas cuya parte está optimizada mediante simulación anidada repetida.

La Figura 12 muestra el sistema que se está simulando. Es una abstracción de, por ejemplo, un banco donde los clientes esperan inicialmente en una cola para un cajero. Después de ser atendido por un cajero, un cliente es atendido por un cajero. Hay otra cola donde los clientes esperan a los cajeros. Los intervalos aleatorios entre llegadas y los tiempos de servicio aleatorios de los cajeros y los cajeros son conocidos. Supongamos que hay un cierto número de empleados que pueden trabajar tanto como cajeros como cajeros. La dirección del banco quiere verificar la manera en que los empleados se asignan como cajeros y cajeros durante un turno típico compuesto por tres períodos: ocupado, inactivo y uno muy ocupado con diferentes intervalos entre las llegadas de los clientes. Para encontrar la mejor política de asignación, se puede utilizar una simulación anidada de la siguiente manera: al comienzo de cada período, la simulación interna repetida probará el comportamiento de la primera etapa para varios números de cajeros (obviamente, el rango es de 1 al número total conocido de empleados). Utilizando los resultados de estos experimentos de simulación interna, la dirección elegirá el número de empleados que trabajarán como cajeros, los demás trabajarán como cajeros. Para simplificar el programa, la decisión la toma el usuario, a quien se le dan los resultados de la simulación interna y luego se le pide que ingrese el número de cajeros y el número de cajeros. El criterio de decisión es el tiempo promedio empleado en la primera etapa. La política en sí también se evalúa por el tiempo promedio empleado en todo el sistema.

Figura 12: Red de colas compuesta por dos servidores multicanal.

El siguiente "programa" es un esquema del programa de simulación (que sigue). Ten en cuenta que el bloque interno precedido por "Simulation" se realiza repetidamente tres veces para todos los posibles números de cajeros. Contiene la declaración de clases similares a las externas. La diferencia radica en un comportamiento más simple del cliente, ya que solo hay una etapa de servicio. Tampoco hay más anidamiento. Básicamente, la simulación interna es similar al ejemplo dado en el capítulo sobre la clase del sistema "Simulation" (enfoque del cliente activo).

Simulation Begin

  Declaration of global variables

  Process Class Generator;  Begin ... End;

  Process Class Customer;  Begin ... End;

 

  Initialize the global experiment

 

  For Period:=1 step 1 until 3 do begin

For Trial:=1 step 1 until MaxClerks do

   Simulation Begin

 

     Declaration of internal global variables

     Process Class Igenerator;  Begin ... end;

     Process Class Icustomer;  Begin ... End;

 

     Perform and evaluate one inner experiment

 

   End of internal simulation;

 

Show results of internal experiments;

Select the best numbers of tellers and cashiers;

 

Perform a part of outer experiment for this period

 

  End For;

  Evaluate the global experiment

End of program;

El siguiente programa es el modelo de simulación anidada con la estructura anterior.

! SIMULACIÓN ANIDADA utilizando la clase SIMULACIÓN de Simula ;

! El ejemplo es un modelo de un banco. Los clientes son primero ;

! atendidos por cajeros, luego por tesoneros. ;

! La tasa de entrada cambia en tres períodos: hay un período ;

! ocupado, luego un período inactivo y nuevamente un período ;

! ocupado. Para cada período, el experimento de simulación ;

! interno repetido simula la primera cola para la tasa de entrada;

! particular y para varios números de servidores. Luego muestra ;

! los resultados (tiempo promedio empleado en el primer servidor);

! y solicita al usuario el número de cajeros y el número ;

! de cajeros. Los cajeros siempre terminan un servicio que ya ;

! ha comenzado. La simulación debería encontrar el ;

! tiempo que los clientes pasan en el banco (promedio y máximo) ;

! para varios números de empleados en los tres períodos. ;

!                                                                                   ;

Simulation Begin

                                    ! Global variables: ;

   Integer Period,Trial;           ! Period, Trial number;

   Real Array MinInt,MaxInt(1:3);  ! Min and Max intervals;

   Real Array Duration(1:3);       ! Duration of periods [min];

   Ref(Head) Queue1,Queue2;        ! The two queues;

   Integer MaxClerks, Tellers, Cashiers;  ! Total numbers;

   Integer BusyTellers, BusyCashiers;  ! Numbers of working clerks;

   Real S1Mean, S1Std, S2Mean, S2Std;  ! Random normal servers;

   Integer SeedG, SeedS1, SeedS2;  ! Seeds of the random generators;

   Long Real TotalTime, MaxTime;   ! Variables for statistics;

   Integer CustomersOut;           ! Number of served customers;

 

 Process Class Generator;

   Begin

   While true do begin

          ! Interval between arrivals: ;

      Hold(Uniform(MinInt(Period),MaxInt(Period),SeedG));

      Activate New Customer(Time);

   End While;

   End of Generator;

 

   Process Class Customer(Arrival); Real Arrival;

   Begin

   Ref(Customer) Next;

   Real Spent;

 

   If (not Queue1.Empty) or (BusyTellers >= Tellers) then

      Wait(Queue1);   ! Has to wait in Queue1;

                      ! Service can start;

   BusyTellers := BusyTellers + 1;

   Hold(Normal(S1Mean, S1Std, SeedS1));  ! This is the teller service;

   BusyTellers := BusyTellers - 1;

 

   If (not Queue1.Empty) and (BusyTellers < Tellers) then begin

      Next :- Queue1.First;

      Next.Out;                      ! First from Queue1 served;

      Activate Next after Current;

   End If;

 

   If (not Queue2.Empty) or (BusyCashiers >= Cashiers) then

      Wait(Queue2);   ! Has to wait in Queue2;

                    ! Service can start;

   BusyCashiers := BusyCashiers + 1;

   Hold(Normal(S2Mean, S2Std, SeedS2));  ! This is the cashier service;

   BusyCashiers := BusyCashiers - 1;

If (not Queue2.Empty) and (BusyCashiers < Cashiers) then begin

      Next :- Queue2.First;

      Next.Out;                      ! First from Queue2 served;

      Activate Next after Current;

   End If;

 

   CustomersOut := CustomersOut + 1;

   Spent := Time - Arrival;

   TotalTime := TotalTime + Spent;

   If Spent > MaxTime then MaxTime := Spent;

   End of Customer;

Procedure Report;       ! Experiment evaluation;   Begin      OutText("  *** Report on external simulation ***"); OutImage;      OutInt(CustomersOut,6); OutText(" customers ready at time ");      OutFix(Time,2,10); OutImage;      OutText("Average time in system: ");      OutFix(TotalTime/CustomersOut,2,10); OutImage;      OutText("Maximum time in system: ");      OutFix(MaxTime,2,10); OutImage;   End of Report;

! MAIN program body;

SeedG  := 11;                 ! Seeds of random variables;
SeedS1 := 13;
SeedS2 := 17;
MinInt(1) := 1; MaxInt(1) := 4;  ! Min and Max intervals;
MinInt(2) := 2; MaxInt(2) := 9;
MinInt(3) := 1; MaxInt(3) := 3;
Duration(1) := 120;           ! Duration of periods;
Duration(2) := 240;
Duration(3) := 120;
MaxClerks  := 6;
S1Mean := 6;                 ! Random normal servers;
S1Std  := 1;
S2Mean := 8;
S2Std  := 2;
Queue1 :- New Head;
Queue2 :- New Head;
Period := 1;
Activate New Generator;

For Period:=1 step 1 until 3 do begin

Real Array TimeSpent(1:MaxClerks);OutText("  *** Results of internal simulation *** Period ");OutInt(Period,1); OutImage;OutText("   Tellers Average time spent"); OutImage;

For Trial:=1 step 1 until MaxClerks do! ********************************************************** ;  Simulation Begin                                       ! Internal Global variables: ;   Real TrialDuration;             ! Internal experiment [min];   Ref(Head) Queue;                 ! The queue;   Integer Servers;                 ! Total number;   Integer BusyServers;             ! Numbers of working clerks;   Integer TrialSeedG,TrialSeedS;   ! Seeds of the random generators;   Long Real TotTime;               ! Variables for statistics;   Integer CustOut;                 ! Number of served customers;

  Process Class IGenerator;   Begin      While true do begin         Hold(Uniform(MinInt(Period),MaxInt(Period),TrialSeedG));         Activate New ICustomer(Time);   ! Interval between arrivals: ;      End While;   End of IGenerator;

 Process Class ICustomer(Arrival); Real Arrival;

   Begin

   Ref(ICustomer) Next;

 

   If not Queue.Empty or (BusyServers >= Servers) then

      Wait(Queue); ! Has to wait in Queue;

                      ! Service can start;

   BusyServers := BusyServers + 1;

   Hold(Normal(S1Mean, S1Std, TrialSeedS));  ! Teller's service;

   BusyServers := BusyServers - 1;

 

   If not Queue.Empty then begin

      Next :- Queue.First;

      Next.Out;                   ! First from Queue served;

      Activate Next after Current;

   End If;

 

   CustOut := CustOut + 1;

   TotTime := TotTime + Time - Arrival;

   End of ICustomer;

 

  ! Internal MAIN program body;

 

TrialSeedG := 7;              ! Seeds for random variables;

TrialSeedS := 23;

Servers := Trial;

TrialDuration := 600;

Queue :- New Head;

Activate New IGenerator;

Hold(TrialDuration);         ! Internal experiment duration;

TimeSpent(Trial) := TotTime/CustOut;

OutInt(Trial,13);

OutFix(TimeSpent(Trial),3,23); OutImage;

 

   End of internal simulation;

! ********************************************************** ;

 

  OutText("Enter the number of tellers : "); OutImage;

  Tellers := InInt;

  OutText("Enter the number of cashiers : "); OutImage;

  Cashiers := InInt;

  Hold(Duration(Period));

  Report;

  OutText("Press Enter to Continue."); OutImage; InImage;

End For;

End of program;

Este es el resultado del modelo de simulación junto con los números ingresados. El número total de empleados es 6, y los números asignados como cajeros y cajeros son ingresados por el usuario. Ten en cuenta el tiempo máximo pasado en el sistema. Se mantiene razonable hasta el tercer período, donde aumenta a 63.93 minutos (nota que el tiempo total promedio de servicio es de 6+8=14 minutos). Por lo tanto, es claro que en el tercer período muy ocupado, un empleado adicional mejoraría considerablemente el comportamiento del sistema. Esta hipótesis fue probada con otra ejecución de la simulación con los mismos datos, excepto con un cajero adicional en el tercer período (4 cajeros, 3 tesoneros). Dio estos resultados: tiempo promedio pasado en el sistema 19.67 (21.84 para 2 cajeros), tiempo máximo pasado en el sistema 36.58, que es la mejora esperada. Por lo tanto, el resultado de la simulación sugiere a la dirección asignar un cajero más en el tercer período muy ocupado, de lo contrario, el sistema se comporta bien con 6 empleados.

*** Results of internal simulation *** Period 1      Tellers Average time spent            1             181.404            2             52.691            3             6.132            4               5.979            5               5.972            6               5.972Enter the number of tellers :3Enter the number of cashiers :3

*** Report on external simulation ***    42 customers ready at time     120.00Average time in system:   18.52Maximum time in system:   25.95Press Enter to Continue.  *** Results of internal simulation *** Period 2      Tellers Average time spent            1             36.620            2             6.090            3               6.045            4               6.038            5               6.038            6               6.038Enter the number of tellers :2Enter the number of cashiers :4  *** Report on external simulation ***    91 customers ready at time 360.00Average time in system:   17.29Maximum time in system:   27.16Press Enter to Continue.  *** Results of internal simulation *** Period 3      Tellers Average time spent            1           205.290            2             103.226            3               7.937            4               5.993            5               5.974            6               5.972Enter the number of tellers :4Enter the number of cashiers :2  *** Report on external simulation ***   119 customers ready at time 480.00Average time in system:   21.84Maximum time in system:   63.93Press Enter to Continue.

¿QUÉ FALLA CON SIMULA?

Simula nunca llegó a ser un lenguaje de uso común y ampliamente adoptado. Hay varias razones que explican este hecho. Aunque todas las razones dependen entre sí, lo siguiente es un intento de agruparlas desde varios puntos de vista.

En general:

  • Nació en un país europeo pequeño.
  • Quedó congelado en 1968.
  • Era costoso.
  • No tiene un entorno de desarrollo integrado (IDE) moderno.
  • Era demasiado complicado.
  • No había suficientes publicaciones.

Características del lenguaje:

  • Facilidades limitadas de acceso a archivos (archivos tipados).
  • Faltaban tipos de datos (registros, conjuntos).
  • No tenía soporte avanzado para paralelismo y tiempo real.
  • No tenía soporte para interfaz gráfica de usuario (GUI).
  • Archivos ejecutables largos para programas cortos.

Características de la programación orientada a objetos (OOP):

  • No tenía herencia múltiple.
  • No tenía interfaces.

Simulación:

  • No había recolección automática de estadísticas.
  • No tenía generador de informes.
  • No tenía instalaciones especializadas útiles (recursos).

REFERENCIAS

Libros/Artículos

Birtwistle, G.M., O.-J. Dahl, B. Myhrhaug and K. Nygaard: SIMULA Begin, AUERBACH Publishers Inc, 1973.

Pooley, R.J.: An Introduction to Programming in SIMULA, Oxford, Blackwell Scientific Publications, 1987.

Kirkerud, B.: Object-Oriented Programming with SIMULA, Addison-Wesley, 1989.

Holmevik, J.R.(1994). " Compiling SIMULA: a historical study of technological genesis." IEEE Annals of the History of Computing, 16 (4), p. 25-37, 1994. The article was also presented at the 18th ASU Conference in 1992, and published in the SIMULA Newsletter Vol.20(1), October 1992.
Gracias a la amable autorización del Sr. Holmevik, puedes descargar una copia local de su artículo Compiling SIMULA.

Periódicos

Proceedings of annual ASU conferences. (First 1973 Oslo).

ASU Newsletter

Sitios web

El hogar de DIRO Simula es una página orientada a Simula alojada en el Département d'informatique et recherche opérationnelle (Université de Montréal). Contiene muchas ideas muy interesantes y referencias adicionales.

ASU (Association of Simula Users) tiene su sede en el ISIMA, Université Blaise Pascal, Francia. Contiene (entre otras cosas) información sobre las conferencias de ASU y una bibliografía completa.

Frequently asked questions

View Our Writer’s Sample Before Crafting Your Own!
Why Have There Been No Great Female Artists?
Place My Order
What was changed:
Sources:
Back to blog

New posts to your inbox!

Stay in touch

Never Spam
Unsubscribe anytime
Thank you!
Your submission has been received!
Oops! Something went wrong while submitting the form.
Save your time by delegating work to our experts!
Support
Plagiarism Report
Negotiable Price
Unlimited Revisions
Write My Paper