Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Очередь без приоритета


Автор: aleknek 2.3.2006, 11:41
Посоветуйте, пожалуйста, как написать алгоритм для программы, реализующую прохождение заявок к процессору. Должно быть двадцать заявок, одна очередь, длина заявок меняется от трёх до семи, при этом квант процессора равен пяти, это означает, если на процессор приходит заявка, длина, которой больше пяти, значит процессором, обрабатывается пять тактов, а оставшиеся идут в конец очереди.

Автор: _hunter 2.3.2006, 11:53
так а в чем проблема?
+ разбей задачу на составляющие -- сначала напиши класс "очередь", потом реализуй "процессор"

Автор: Демо 2.3.2006, 13:54
Задачу можно разбить на более мелкие субъекты:

1. Заявка.
Атрибуты: Длина заявки.

2. Очередь.
Атрибуты: Максимальная длина очереди.

3. Процессор.
Атрибуты: Максимальная длина шага(кванта).

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

Собственно, это и все.

Автор: aleknek 2.3.2006, 23:18
Мне не совсем понятно, как это все надо написать, просто я новичок в этом деле и классы я еще никогда не писал, на Delphi я писал программки, но они были очень примитивные и простые, а тут задали курсовую я и задумался, если можно помогите пожалуйста в написании.

Заранее благодарен.

Автор: Демо 2.3.2006, 23:55
Вот простейший класс - "Заявка"

Код

  TClaim=class
  private
    FCount: Integer;
  public
    constructor Create;
    function DecCount: Integer;

    property Count: Integer read FCount;
  end;

{ TClaim }

constructor TClaim.Create;
begin
    FCount := Random(7)+1;
end;

function TClaim.DecCount: Integer;
begin
    if FCount>0 then Dec(FCount);
    Result := FCount;
end;


Автор: aleknek 3.3.2006, 00:04
Спасибо огромное, буду пробовать.

Автор: Демо 3.3.2006, 00:09
Следующий класс - "Очередь".

Очередь можно сделать как наследник стандартного класса Delphi - TList:

Код

  TTurn=class(TList)
  private
    function GetItems(Index: Integer): TClaim;
    procedure SetItems(Index: Integer; const Value: TClaim);
  public
    destructor Destroy; override;
    function Add(Item: TClaim): Integer;
    procedure Delete(Index: Integer);
    procedure MoveToLast;

    property Items[Index: Integer]: TClaim read GetItems write SetItems;
  end;

{ TTurn }

function TTurn.Add(Item: TClaim): Integer;
begin
    Result := Add(Item);
end;

procedure TTurn.Delete(Index: Integer);
begin
    TClaim(Items[Index]).Free;
    inherited Delete(Index);
end;

destructor TTurn.Destroy;
begin
  while Count>0 do Delete(0);
  inherited;
end;

function TTurn.GetItems(Index: Integer): TClaim;
begin
    Result := Items[Index];
end;

procedure TTurn.MoveToLast;
begin
    Add(Items[0]);
    inherited Delete(0);
end;

procedure TTurn.SetItems(Index: Integer; const Value: TClaim);
begin
    Items[Index] := Value;
end;


Автор: Демо 3.3.2006, 00:40
Ну и, наконец, класс 'Процессор':

Код

  TProcessor=class
  private
    FMaxClaims: Integer;
    FTurn: TTurn;
    procedure SetMaxClaims(const Value: Integer);
    procedure ExecStep(Claim: TClaim);
  public
    constructor Create(MaxClaims: Integer=20);
    destructor Destroy; override;
    procedure AddClaim(Claim: TClaim);
    procedure Execute;

    property MaxClaims: Integer read FMaxClaims write SetMaxClaims;
  end;

{ TProcessor }

procedure TProcessor.AddClaim(Claim: TClaim);
begin
    if FTurn.Count=FMaxClaims
        then raise Exception.Create('Нельзя добавить новую заявку, превышено максимальное число заявок - '+IntToStr(FMaxClaims));
    FTurn.Add(Claim);
end;

constructor TProcessor.Create(MaxClaims: Integer);
begin
    FMaxClaims := MaxClaims;
    FTurn := TTurn.Create;
end;

destructor TProcessor.Destroy;
begin
    FTurn.Free;
    inherited;
end;

procedure TProcessor.ExecStep(Claim: TClaim);
begin
    Claim.DecCount;
end;

procedure TProcessor.Execute;
var
    i: Integer;
begin
    while FTurn.Count>0 do
    begin
      for i := 0 to MaxSteps-1 do
      begin
          ExecStep(FTurn[0]);
          if FTurn[0].Count=0 then break;
      end;
      if FTurn[0].Count=0
        then FTurn.Delete(0)
        else FTurn.MoveToLast;
    end;
end;

procedure TProcessor.SetMaxClaims(const Value: Integer);
begin
    if Value=FMaxClaims then Exit;
    if (FTurn.Count=FMaxClaims) and (Value<FMaxClaims)
        then raise Exception.Create('Нельзя установить максимальное число заявок в '+IntToStr(Value)+
                                    ', число текущих заявок в обработке - '+IntToStr(FTurn.Count));
    FMaxClaims := Value;
end;


Добавлено @ 00:43
Вот тебе весь получившийся модуль:

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
    MaxSteps=5;
type

  TClaim=class
  private
    FCount: Integer;
  public
    constructor Create;
    function DecCount: Integer;

    property Count: Integer read FCount;
  end;

  TTurn=class(TList)
  private
    function GetItems(Index: Integer): TClaim;
    procedure SetItems(Index: Integer; const Value: TClaim);
  public
    destructor Destroy; override;
    function Add(Item: TClaim): Integer;
    procedure Delete(Index: Integer);
    procedure MoveToLast;

    property Items[Index: Integer]: TClaim read GetItems write SetItems; default;
  end;

  TProcessor=class
  private
    FMaxClaims: Integer;
    FTurn: TTurn;
    procedure SetMaxClaims(const Value: Integer);
    procedure ExecStep(Claim: TClaim);
  public
    constructor Create(MaxClaims: Integer=20);
    destructor Destroy; override;
    procedure AddClaim(Claim: TClaim);
    procedure Execute;

    property MaxClaims: Integer read FMaxClaims write SetMaxClaims;
  end;

  TForm1 = class(TForm)
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TClaim }

constructor TClaim.Create;
begin
    FCount := Random(7)+1;
end;

function TClaim.DecCount: Integer;
begin
    if FCount>0 then Dec(FCount);
    Result := FCount;
end;


{ TTurn }

function TTurn.Add(Item: TClaim): Integer;
begin
    Result := Add(Item);
end;

procedure TTurn.Delete(Index: Integer);
begin
    TClaim(Items[Index]).Free;
    inherited Delete(Index);
end;

destructor TTurn.Destroy;
begin
  while Count>0 do Delete(0);
  inherited;
end;

function TTurn.GetItems(Index: Integer): TClaim;
begin
    Result := Items[Index];
end;

procedure TTurn.MoveToLast;
begin
    Add(Items[0]);
    inherited Delete(0);
end;

procedure TTurn.SetItems(Index: Integer; const Value: TClaim);
begin
    Items[Index] := Value;
end;

{ TProcessor }

procedure TProcessor.AddClaim(Claim: TClaim);
begin
    if FTurn.Count=FMaxClaims
        then raise Exception.Create('Нельзя добавить новую заявку, превышено максимальное число заявок - '+IntToStr(FMaxClaims));
    FTurn.Add(Claim);
end;

constructor TProcessor.Create(MaxClaims: Integer);
begin
    FMaxClaims := MaxClaims;
    FTurn := TTurn.Create;
end;

destructor TProcessor.Destroy;
begin
    FTurn.Free;
    inherited;
end;

procedure TProcessor.ExecStep(Claim: TClaim);
begin
    Claim.DecCount;
end;

procedure TProcessor.Execute;
var
    i: Integer;
begin
    while FTurn.Count>0 do
    begin
      for i := 0 to MaxSteps-1 do
      begin
          ExecStep(FTurn[0]);
          if FTurn[0].Count=0 then break;
      end;
      if FTurn[0].Count=0
        then FTurn.Delete(0)
        else FTurn.MoveToLast;
    end;
end;

procedure TProcessor.SetMaxClaims(const Value: Integer);
begin
    if Value=FMaxClaims then Exit;
    if (FTurn.Count=FMaxClaims) and (Value<FMaxClaims)
        then raise Exception.Create('Нельзя установить максимальное число заявок в '+IntToStr(Value)+
                                    ', число текущих заявок в обработке - '+IntToStr(FTurn.Count));
    FMaxClaims := Value;
end;

initialization
    Randomize;
end.



А в качестве тренировки предлагаю самому добавить в TProcessor установку разиера кванта (вместо константы MaxSteps), а также отладить и исправить все это дело как нужно.

Автор: aleknek 3.3.2006, 00:44
Спасибо, завтра попытаюсь со всем этим разобраться и довести до ума.

Автор: aleknek 15.3.2006, 22:31
Все равно я чего то недопонимаю, пытаюсь создать приложение, в котором будут видны заявки, которые обрабатываются процессором, а какие идут в конец очереди,т.е необходимо чтобы было десять таблиц, где дельта Т изменяеться от одного до десяти ( где дельта-время поступления заявки в систему ), не могу понять как? Посоветуйте, пожалуйста .

Автор: _hunter 16.3.2006, 11:47
неможеш понять что?
как 10 таблиц на форму прилепить?
+ зачем 10 таблиц? может проще в одной таблице 11 чтолбцов сделать?

Автор: aleknek 17.3.2006, 16:54
Таблица я думаю должна быть одна, в которой меняя дельта Т (которых, будет десять) , можно будет отследить значения FCount , а не понятно мне как в классе ТForm отобразить данные из классов TClaim, TTurn и TProcessor, может это очень примитивно, но я пока этого не понимаю. Заранее благодарен.

Автор: _hunter 17.3.2006, 17:53
это все хорошо, но вопрос где?

Автор: Guedda 17.3.2006, 17:58
Цитата

не понятно мне как в классе ТForm отобразить данные из классов TClaim, TTurn и TProcessor, может это очень примитивно, но я пока этого не понимаю. Заранее благодарен.

Вот это и вопрос.

Смотря, где ты хочешь отобразить...

Автор: aleknek 17.3.2006, 18:24
Все это я хочу отобразить на стандартной форме класса TForm.

Автор: _hunter 17.3.2006, 18:32
это не вопрос ( точнее вопрос в раздел "работа" )
в чем, вообще, проблема? в сетку данные позаносить?

Автор: aleknek 17.3.2006, 22:42
Проблема в том, что не могу понять куда надо данные занести, чтобы они отображались на форме, в класс TForm или в классы TClaim, TTurn и TProcessor.

Автор: Guedda 18.3.2006, 10:51
Создаешь переменную надобного тебе класса, и все в эту переменную пихаешь, что нужно.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)