Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Помогите выбрать тип данных [D7, XP]


Страницы:   1 2

Xandr001 ©   (2010-07-20 18:47:00) 

В общем есть такая формальная модель:
Датчики -> "нейронная" сеть -> Исполнительное устройство.
Система работает тактами (100 в секунду). Все компоненты системы тактируются от одного часового устройства.

Датчик выдает импульсы, распределенные в течении секунды в зависимости от измеряемого параметра.

"Нейрон" представляет собой некий черный ящик. Имеет неограниченное чило входов и выходов. Каждый "нейрон" имеет порог срабатывания. Порог срабатывания это число импульсов, пришедшее за один такт на входы. При достижении этого числа, отдает импульс на выходы. Входы бывают двух видов:
1) нормальный - при появлении в течении такта импульса на этом входе, к переменной хранящей число импульсов прибавляется 1, пришедшее за такт.
2) блокирующий - при появлении в течении такта импульса на этом входе, в независимости от достижения или недостижения порога срабатывания, на выходы импульс не подается.
импульсы отдаются только в конце такта (считается, что передача и обработка импульса занимет меньшее время чем длится такт).
Чтобы было понятно как работают "нейроны", приведу схему небольшой сети:
-> обозначает нормальный вход
-о обозначает блокирующий вход
цифра в скобках обозначает "нейрон" и порог его срабоатывания.

Сеть номер 1:
(датчик)->(1)->(исполнительное устройство)
Организует задержку в 1 такт, т.е: 1й такт - в конце такта датчик отдает импульс,  2й такт - нейрон принял его, в конце такта отдал импульс на выход, 3й такт - исполнительное устройство приняло импульс, выполнило операцию.

Сеть номер 2:
                    >(2)  
                  /    ^  \
                /      |    о
(датчик)->(1)->(1)->(1)->(исполнительное устройство)
Выделяет из серии импульсов идущих с датчика - один последний, если импульсы разделены хотябы одним тактом, работает просто как задержка.
ЧТобы было понятно приведу табличку (0 соответствует отсутствию импульса в течении такта, 1 - импульс, одна цифра - один такт):
Выход датчика  | Вход исполнителя
============+==============
01010101         | 00010101
11100101         | 00000101
11111111         | 00000000
============+==============

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

Суть задачи - симуляция действия таких систем на Delphi 7.
Суть проблемы - непонятно как это все организовать. Т.е. именно как представить все это хозяйство, а уже организовать действие такой системы я смогу сам. Как поступить? Динамические массивы? Графы? ООП?
Подскажите пожалуйста, хотя бы примерную структуру данных, сижу в ступоре уже довольно долго.


Xandr001   (2010-07-21 20:02:00) [1]

Извините. разобрался :(


Xandr001   (2010-07-21 19:26:00) [2]

и опять ошибка...

В общем правильно так:

Допустим имеем:

type
TParent1 = class;
TParent2 = class;

TParent1 = class
State: boolean;
end;

TParent2 = class
Lk1, Lk2: TParent1;
end;

TChild1 = class(TParent1)
a:Integer;
end;

TChild2 = class(TParent1)
b:Integer;
end;


Далее, создаем экземпляры:


var
Parent: TParent1;
Link1: TChild1;
Link2: TChild2;

procedure go()
begin
link:= TParent2.Create;
Link1:= TChild1.Create;
Link2:= TChild2.Create;
link.lk1:=Link1;
link.lk2:=Link2;


И вопрос звучит так:

Можно ли при такой конструкции изменить значения Link1.а и Link2.b через Link?

т.е. что-то типа:
if link.lk1.ClassName='TChild1' then ...

Возможно ли вообще?
Если можно, то как? Если нельзя, то при какой можно и как?


Xandr001   (2010-07-21 19:22:00) [3]

ой!

Это:
var
Parent: TParent1;
Link1: TSensor;
Link2: TAnnunciator;


читать как:

var
Parent: TParent1;
Link1: TChild1;
Link2: TChild2;


Сочинял на ходу...


Xandr001   (2010-07-21 19:20:00) [4]


> придется таки в теорию зарыться...

ради этого, в общем то, все и затевалось.

У меня вот такой вопрос тут возник (и маленькая надежда обойтись малой кровью):

Допустим имеем:

type
TParent1 = class;
TParent2 = class;

TParent1 = class
State: boolean;
end;

TParent2 = class
Lk1, Lk2: TParent1;
end;

TChild1 = class(TParent1)
a:Integer;
end;

TChild2 = class(TParent1)
b:Integer;
end;


Далее, создаем экземпляры:


var
 Parent: TParent1;
 Link1: TSensor;
 Link2: TAnnunciator;

procedure go()
begin
link:= TParent2.Create;
Sensor:= TChild1.Create;
Annunciator:= TChild2.Create;
link.lk1:=Sensor;
link.lk2:=Annunciator;
end;


Можно ли при такой конструкции изменить значения Sensor.а и Annunciator.b через Link?

т.е. что-то типа:
if link.lk1.ClassName='TChild1' then ...

Возможно ли вообще?
Если можно, то как? Если нельзя, то при какой можно и как?


han_malign   (2010-07-21 18:12:00) [5]


> Это не дерево, это граф.

- это орграф, причем нагруженный...

> два элемента соеденины двумя линиями разной направленности, или что-то другое?

- несколько узлов могут быть соединены в цикл, причем через один узел может проходить несколько различных циклов
links:(3,2)( 1,2)(2,4)(4, 1)(4,5)
нотогда может быть надо
links:(3,2) ( 1,2)(2,4)(4, 1) ( 1,2)(2,4)(4,5) ???
и возникает вопрос - где должна быть точка входа в цикл, и когда этот порочный цикл надо разорвать и что за чудесные состояния мы при этом получим(учитывая что они все-таки итеративно накапливаются, а не за один "такт")... либо там вообще системы уравнений строить надо...

Если таки итеративно и обратная связь "мгновенная" то цикл должен быть "функцией неподвижной точки" - то есть, через конечное число (К) итераций цикла, состояние всех узлов цикла должно устаканиться ( Node[i](K) == Node[i](K+1), где i пробегает индексы всех узлов всех пересекающихся циклов). Детектирование того что цикл осциллирует или расходится, в общем случае - без ограничения максимального (K), потребует необозримых ресурсов. В приведенном исполнении - с ограничением по (K) - можно тупо продублировать циклы (K)-раз и надеяться что они таки сходятся.

Если обратная связь с задержкой(по тактам)(классический рекуррентный фильтр), то можно увеличить количество узлов и циклов сброса/перехода(для запоминания промежуточных состояний).
Например для простенькой обратной связи
 s -> b1 --> b2 --> O
      ^______|
с задержкой в один такт:
Узлы: s1 b1 b2 ~b2O
[начало такта]
Возбуждение: s1
сброс: b1 b2(1) O
(s1,b1)( ~b2,b1)(b1,b2)
сброс: ~b2
(b2, ~b2)(b2,O)
[конец такта]
(естественно в начале "эволюции" состояние ~b2 надо чем то инициализировать)
Или можно завести кольцо состояний Node [j mod K][i] и соответственно Nodes [(j + Links[i]. back) mod K][Links[i].target], или еще куча вариантов...

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


Jeer   (2010-07-21 17:30:00) [6]


> Вообще то могут объединяться, схемы с открытым выходом


Да это понятно, я о его схеме, а не о конкретных элементах.
Так там еще и трехстабильные выходы существуют.


Anatoly Podgoretsky   (2010-07-21 16:37:00) [7]

> Jeer  (21.07.2010 16:29:26)  [26]

Вообще то могут объединяться, схемы с открытым выходом, но это обходится
созданием виртуально устройства M-OR-1 и опять приходим к один выход.


Jeer   (2010-07-21 16:29:00) [8]


> Xandr001   (21.07.10 15:24) [25]


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


Xandr001   (2010-07-21 15:24:00) [9]


> Очевидно же, что у Вас не сеть, а дерево - вот и используется
> "деревянный подход. А каждый узел сети - объект с нужными
> свойствами.

Откуда это очевидно?
Насколько я понимаю, дерево это структура начинающаяся одним корнем корне и заканчивающася конечным множеством листьев. каждый узел, кроме корневого, содержит связи с родителем и с потомками. Никаких связей кроме родитель-потомок в дереве не существует.
Если же теперь посмотреть на схему №2 в [0], то можно увидеть следующую картину: один вход, один выход, четыре узла. Даже если представить эту схему неуравновешенным бинарным деревом, то ни о какой связи между (2) и самой правой (1) говорить не приходится, а она есть...
Это не дерево, это граф.


> han_malign  (21.07.10 14:10) [24]

В таких случаях на профильных форумах говорят: пошел курить даташит)
Спасибо большое, буду думать.


> Конечно с обратными связями здесь нетривиальная проблема...

Под обратной связью тут понимается ситуация когда два элемента соеденины двумя линиями разной направленности, или что-то другое?
И что за проблема? пока не очень въехал в суть...


han_malign   (2010-07-21 14:10:00) [10]

см. Игорь Шевченко ©   (20.07.10 22:20) [8]
где-то, примерно так:
S - количество сенсоров
B - количество черных ящиков
O - количество индикаторов
Nodes[S+B+O]: {accum, lock: cardinal}
Links[SXB+BXB+BXO)]: {source, target, threshold: cardinal; action: integer};
возбуждение
for i:=0 to S-1 do Nodes[i].accum:= random(1);
for i:=S to S+B+O-1-1 do begin
  Nodes[i].accum:= 0;
  Nodes[i].lock:= 0;
end;
орграф
for i:=Low(Links) to High(Links) do
     with(Nodes[Links[i].source])do
         if( (lock = 0) and (accum >  Links[i].threshold)then
            if( Links[i].action > 0 )then
               inc(Nodes[Links[i].target].accum, Links[i].action)
            else
               dec(Nodes[Links[i].target].lock, Links[i].action);
индикация
for i:=S+B to S+B+O-1 do if( Nodes[i].accum > 0 ) ...;

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


Anatoly Podgoretsky   (2010-07-21 13:06:00) [11]

> Xandr001  (21.07.2010 12:31:21)  [21]

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


Jeer   (2010-07-21 13:01:00) [12]

Очевидно же, что у Вас не сеть, а дерево - вот и используется "деревянный подход. А каждый узел сети - объект с нужными свойствами.


Xandr001   (2010-07-21 12:31:00) [13]


> Связь достаточно делать только по входам, если еще ее дубировать
> по выходам, то придется заводить кучу списков.

это именно то, о чем я говорил в [4] и в [12]
Можно по входам, можно по выходам. При таком подходе, в объекте "сеть" получится 3 списка:
список элементов входы которых являются входами сети,
список элементов выходы которых являются выходами сети,
список всех элементов сети.
Та же самая избыточность, хотя списков меньше. Или можно как-то по другому?


Anatoly Podgoretsky   (2010-07-21 12:23:00) [14]

> Xandr001  (21.07.2010 12:01:17)  [17]

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


Xandr001   (2010-07-21 12:13:00) [15]

threshold - порог срабатывания элемента


Xandr001   (2010-07-21 12:12:00) [16]

numIn, numOut - номера входов и выходов соедияемых элементов
stateIn, stateOut - состояния входов и выходов (0 или 1)


Xandr001   (2010-07-21 12:01:00) [17]


> Блин. Легче принципиалку нарисовать, чем программу...

Это да. Попытался нарисовать - так  на обычной логике просто решается, либо еще проще - на операционниках.


> Попробуй для начала "раздробить" общую задачу на частные

Тут попытался изложить всю задачу целиком из-за того что, обычно задаешь частный вопрос, а в ответ слышишь: А зачем это надо? Опиши полную задачу.

Но попытаюсь более детально описать суть:
Итак необходимо смоделировать поведение сети неких черных ящиков.
Сеть имеет "неограниченное" количество входов и выходов (ну в пределах здравого смысла, конечно, т.е. не сто тысяч и не миллион. Можно задаться к.л. порогом, например 20 или 500...).
Вход и выход могут иметь 2 состояния: 0 или 1.

Работа сети происходит дискретно, т.е. имеется такое понятие как "такт". В ходе каждого такта происходит следующее:
1) считывается состояние входов
2) эта информация обрабатывется
3) устанавливается состояние выходов

Каждый элемент сети (черный ящик) представляет собой элемент, имеющий порог срабатывания (устанавливается при создании элемента, в течении его жизни не меняется), счетчик, входы и выходы. Точно такие же как и у сети в целом (что естественно, т.к. входы и выходы сети есть соответствующие выводы "крайних" ее элементов).
Замечу, что говоря про отсутствие несоединенных элементов я говорил в контексте представления мной датчиков и исполнителей как таких же элеметов, толко с ограничееной функциональностью, т.е. датчик имеет только выход, а испольнитель - только вход. Но можно и отойти от такой концепции
Элементы сети связаны между собой линиями передачи данных. Передача происходит мгновенно. Передача данных осуществляется только в одном направлении, т.е. связь всегда соединяет один выход с одним входом. Связи могут быть двух типов:
1) нормальная - передает 1 на вход, если на выходе 1, и передает 0 на вход, если на выходе 0.
2) блокирующая - передает элементу сети сигнал установить 0 на всех выходах, независимо ни от чего.
Тут я подумал что неплохо бы ввести еще и инвертирующую линию

Работа каждого элемента так-же происходит дискретно. В ходе каждого такта происходит следующее:
1) сбросить счетчик в 0, установить состояние выходов в 0
2) считывается состояние входов
3) если пришел сигнал по блокирующей линии, то установить все входы в 0, и закончить работу
4) если сигнал по блокирующей линии не пришел, то прибавить количество 1 к счетчику
5) если счетчик >= порога срабатывания установить состояние выходов в 1, иначе - закончить работу.

Каждый такт сети совпадает с тактом каждого ее элемента.

Итак, какие у меня возникли вопросы:
Как будет лучше: т.к. связи бывают нескольких типов, то представить их как отдельный объект, либо как отдельные виды входов(выходов) элемента сети?
Какую структуру представления элементов и связей лучше выбрать?

Пока я думаю примерно в такую сторону:

type
TCell = class;
TConnection = class;
TypeConnection = (normal, invert, block);

TCell = class
  pIn, pOut: array of TConnection;
  threshold: ShortInt;
end;

TConnection = class
  pIn, pOut: TCell;
  numIn, numOut: ShortInt;
  stateIn, stateOut: Boolean;
  Connection: TypeConnection;

end;

Подскажите где не прав, и можно ли как-то более правильно представить это все?


Германн   (2010-07-21 02:23:00) [18]


> Юрий Зотов ©   (21.07.10 00:22) [14]
>
> Блин. Легче принципиалку нарисовать, чем программу...
>

+1
Автору.
Попробуй для начала "раздробить" общую задачу на частные.


Jeer   (2010-07-21 01:03:00) [19]


> Xandr001   (20.07.10 21:04) [1]
> Не тот форум,


Увы  - это так.

Для моделирования:
- электротехнических схем - xSpice и т.п.
- динамических схем - VisSim, MathLab и пр.
- стохастическое, эволюционное, ситуационное и пр. моделирование - см. к примеру GPSS и пр.


Юрий Зотов   (2010-07-21 00:22:00) [20]

Блин. Легче принципиалку нарисовать, чем программу...


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо