Просмотр полной версии : Критическое время выполнения блока на ST.
alexey001
01.08.2024, 14:05
Есть такой код:
for i:=1 to 3 do
for j := 1 to 3 do
if LArr[j] < LArr[j+1] then
tmp1 := LArr[j];
LArr[j] := LArr[j+1];
LArr[j+1] := tmp1;
tmp2 := AArr[j];
AArr[j] := AArr[j+1];
AArr[j+1] := tmp2;
end_if;
end_for;
end_for;
В симуляции все ок , при загрузке в реальную ПР-ку сразу падает в останов.
Если развернуть внешний цикл (на 3 одинаковых блока) - все работает. Также , если убрать часть кода с tmp2 может заработать с внешним циклом (хотя обычно тоже валится - как повезет).
По какому критерию работает (wathdog?) для ST?
Бубновый валет говорит что с индексами навалили
Есть такой код:
for i:=1 to 3 do
for j := 1 to 3 do
if LArr[j] < LArr[j+1] then
tmp1 := LArr[j];
LArr[j] := LArr[j+1];
LArr[j+1] := tmp1;
tmp2 := AArr[j];
AArr[j] := AArr[j+1];
AArr[j+1] := tmp2;
end_if;
end_for;
end_for;
вот что на такой вопрос ответила нейросеть
Этот фрагмент кода представляет собой пример сортировки пузырьком для двух связанных массивов LArr и AArr. Сортировка пузырьком — это простой алгоритм сортировки, который работает путем многократного прохождения по списку или массиву, сравнивая каждую пару соседних элементов и меняя их местами, если они находятся в неправильном порядке.
В данном случае, алгоритм применяется к двум массивам одновременно, предполагая, что эти массивы имеют одинаковую длину и соответствуют друг другу (то есть элементы на одном индексе в LArr соответствуют элементам на том же индексе в AArr). Это может быть полезно, например, при сортировке пар чисел, где одно число должно оставаться с тем же индексом, что и другое после сортировки.
Давайте разберем шаги этого кода:
Цикл внешний (for i:=1 to 3 do): Проходит через каждый элемент массива LArr и AArr, начиная с первого элемента и заканчивая третьим элементом (включительно). Количество проходов определяет количество итераций сортировки пузырьком.
Цикл внутренний (for j := 1 to 3 do): Для каждого элемента, пройденного внешним циклом, выполняется еще один цикл, который проходит по всем элементам массива до последнего (в данном случае, до третьего элемента).
Сравнение и обмен: Внутри внутреннего цикла происходит сравнение текущего элемента LArr[j] с следующим элементом LArr[j+1]. Если текущий элемент меньше следующего, то происходит обмен значений между этими элементами. То же самое делается для массива AArr.
Обмен значениями: Значения временной переменной tmp1 используются для хранения значения текущего элемента перед его заменой, а затем используется для замены следующего элемента. Аналогично для массива AArr, но здесь используется временная переменная tmp2.
Этот процесс повторяется для всех элементов массива, приводя к тому, что большие элементы "плавают" к концу массива, а меньшие — к началу. После завершения всех проходов, массивы будут отсортированы в порядке возрастания.
Важно отметить, что эффективность сортировки пузырьком зависит от количества проходов и размера массива. Для больших массивов существуют более эффективные алгоритмы сортировки.
и на предложение что можно улучшить написала следующее
Для улучшения производительности алгоритма сортировки пузырьком можно использовать два основных подхода:
Использование флага для отслеживания обмена элементов: Если в процессе одного прохода не было выполнено ни одного обмена, это означает, что массив уже отсортирован, и дальнейшие проходы можно пропустить. Это позволяет уменьшить количество необходимых проходов и оптимизировать алгоритм.
Сравнение только смежных элементов: После каждого прохода внешнего цикла самый большой элемент в несортированной части массива перемещается в конец массива. Поэтому, в последующих проходах, можно пропускать сравнение уже отсортированных элементов, что также сокращает количество операций.
Применим эти оптимизации к вашему коду:
var
LArr: array[1..3] of Integer;
AArr: array[1..3] of Integer;
i, j, swapped: Boolean;
begin
swapped := True;
repeat
swapped := False;
for i := 1 to 3 do
begin
if (i < 3) and (LArr[i] > LArr[i + 1]) then
begin
Swap(LArr[i], LArr[i + 1]);
Swap(AArr[i], AArr[i + 1]);
swapped := True;
end;
end;
until not swapped;
end;проверте вдруг она не ошиблась
...проверте вдруг она не ошиблась
Она откуда знает что:
..
LArr: array[1..3] of Integer;
..
for i := 1 to 3 do
..
if (i < 3) and (LArr[i] > LArr[i + 1]) then
тут* вычисляется не полностью?
*в ПР. Причем тут может быть различие с эмуляцией.
А меня интересует что именно в конце хотел получить автор?
kondor3000
01.08.2024, 15:59
Да всё просто, переменные i и j , становятся равны 4, что в Лоджике приводит к переполнению массива. Укажите массив как array[1..4]
или сделайте переменные i и j, от 1 до 2 и не будет ошибок.
alexey001
02.08.2024, 01:45
Не весь код приводил. С определением массивов там все ок
LArr: array [1..4] of real;
AArr: array [1..4] of udint; - вот так определены;
потом заполняются
LArr[1]:=L1; LArr[2]:=L2; LArr[3]:=L3; LArr[4]:=L4;
AArr[1]:=1; AArr[2]:=2; AArr[3]:=3; AArr[4]:=4;
на а потом пузырьковая как правильно заметили.
Не весь код приводил..:
На сьезде гадалок утверждают что до сих пор не все, как минимум есть поле с квадратиками и типы для tmp1 и tmp2.
Гадалки не работают с скриншотами и выписками.
Добавлю, что "пузырёк" - это алгоритм из двух вложенных циклов, у которых переменные циклов изменяются в разных направлениях - i увеличивается, j уменьшается.
На Pascal
{ Сортировка "пузырьком" }
procedure BubbleSort(var A: mas; N: integer);
var
i, j: integer;
x: byte;
begin
for i := 1 to N - 1 do
for j := N downto i + 1 do
if A[j] < A[j - 1] then
begin
x := A[j];
A[j] := A[j - 1];
A[j - 1] := x;
end;
end;
Или
procedure BubbleSort(var A: TArray; N: integer);
var
i, j: integer;
x: integer;
begin
for i := 1 to N - 1 do
begin
j := N;
repeat
if (A[j] < A[j - 1] then
begin
x := A[j];
A[j] := A[j - 1];
A[j - 1] := x;
end;
Dec(j);
until (j<=i);
end;
end;
Можно подумать, и сделать repeat внешним циклом, тогда станет возможным выход при отсутствии обмена.
Встречное направление обязательно, чтобы сортировался и начальный элемент, а не только конечный.
Но в любом случае - это ограниченный во времени процесс, даже без оптимизации. Тем более, для 4 пар элементов двух массивов - всего 4*4=16 сравнений и перестановок.
Поэтому предлагаю топикстартеру проверять на какой-нибудь минимальной тестовой программе - где имеются только пара массивов и процедура сортировки.
kondor3000
02.08.2024, 19:13
Готовая пузырьковая сортировка для Лоджика, давно выложена в Функциях http://ftp-ow.owen.ru/softupdate/OWEN%20Logic/STFunctions/fMaxI_MinI.txt
Функции для Лоджика https://owen.ru/forum/showthread.php?t=37203
alexey001
04.08.2024, 00:30
Попробую как будет время с чем нибудь другим. Собственно проблема то не в том какой алгоритм сортировки использован (просто для 4х элементов все будут более менее равны по скорости, ну и он в голову конечно 1й приходит) а видимо в том что если у нас есть цикл и какая либо работа внутри с массивом то используется некий wathdog который решает что мы ушли в слишком долгий цикл или бесконечный. Возможно на этапе компиляции Logic пытается примерно оценить количество операций / время выполнения конструкции и иногда ошибается с таким вот результатом.
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot