Консультация № 185632
20.03.2012, 17:43
72.20 руб.
20.03.2012, 17:48
0 20 1
Здравствуйте! У меня возникли сложности с таким вопросом:
Написал программу, генерирующю последовательность случайных цифр, но она не выдает результата при нажатии на 2-ю кнопку (пустой экран). Возможно это из за фигурных скобок. Результат она должна будет записать переменную(которая доступна будет с любой странички сайта).
Программа должна работать с большими числами (напр. 1000), которые будут браться из БД.
файл php, который не работает
рабочий исходник delphi

если поставить еще одну фигурную скобку после первой кнопки, то ругается на переменные, используемые внутри функций.
Функция, которая выдает результат
Код:
function  SortVuvod(){}


Я пытался переделать программу из delphi на php, возможно что то напортачил. Первая кнопка работает, а вторая не выводит результат. Помогите пожалуйста исправить код.

Обсуждение

давно
Старший Модератор
312929
1973
23.03.2012, 07:16
общий
Судя по всему, программа реализует некий вариант генетического алгоритма. Расскажите, пожалуйста, поподробнее, какой именно алгоритм используется (в частности, какая целевая функция).
Неизвестный
23.03.2012, 17:27
общий
23.03.2012, 18:10
Да, используется генетический алгоритм. Сам алгоритм решения и задание я прикрепил в это сообщение.
Но сдесь весь алгоритм не нужно реализовывать. Только те, что есть в программе.
Сдесь идея такая, чтобы постоянно генерировать новые цифры. Но у меня там просто в функция в переменные значения записывать не хочет, из за этого скорее всего и не работает.
Прикрепленные файлы:
7d397c0122b5d9853e5075d8678666de.rar
Неизвестный
23.03.2012, 22:04
общий
При нажатии на кнопку в переменную занеслось значение. Но при использовании в функции значение в переменной испаряется, даже при использовании $GLOBALS['переменная']. Ума не приложу что с этим делать.
Неизвестный
26.03.2012, 10:55
общий
26.03.2012, 12:03
что касается передачи переменных между страницами - допишите ВО ВСЕХ СКРИПТАХ первой строкой, самой первой, до всякого вывода, до формы эту строку:

Код:
<? session_start(); ?>


ну и плюс - зарегистрировать нужные переменные в сессии, например, так:

Код:
session_register ("RazmerPop", "nKros", "nMut", "PopRab", "MasPopRab", "Vuvod", "SaveP");


(Внимание! Данная функция была помечена УСТАРЕВШЕЙ начиная с версии PHP 5.3.0 и была УДАЛЕНА в версии PHP 5.4.0.)


Кроме этого, совершенно непонятна структура массивов (вроде бы похоже на матрицу, две строки от 1 до 100, третья состоит из единственного нолика - это, как минимум, странно )

Ну и далее, соответственно обращение к этим массивам, например, к выводу:

echo ($Vuvod[$i]['KolRabMesto'][$k]);

массив был объявлен, как
array(
"Rab"=>range(1,100),
"KolRabMesto"=>range(1,100),
"TimeCritical"=>0);

то есть, повторюсь "как бы" двумерный - а эху передаётся элемент "якобы" трёхмерного массива, как так? И координата ['KolRabMesto'] это как бы имя строки, должна идти первой... непонятненько...
Неизвестный
26.03.2012, 11:56
общий
26.03.2012, 12:03
У меня оказывается еще старый php интерпретатор, версия 5.2.0. Напишу как вы скзали, все равно незнаю чем заменяется в новых версиях
Код:
session_register 

только во как такие массивы в сессию засовывать, непонятно:
Код:
$_Session=$Razmerpop[$i]['rab'][$k]
как то так, что ли
Неизвестный
26.03.2012, 12:12
общий
26.03.2012, 13:40
нет, нужно так:

$_SESSION['Razmerpop'] = $Razmerpop; // сохраняется весь массив , чтобы потом к нему обратиться, можно сделать обратную процедуру:

$Razmerpop = $_SESSION['Razmerpop'];

циклы при этом никакие не нужны.

ЗЫ: (важное) не совсем в тему передачи переменных, но всё же: ПХП чувствителен к регистру, $Ostanov и $ostanov - это разные переменные )))
Неизвестный
26.03.2012, 15:40
общий
то есть, повторюсь "как бы" двумерный - а эху передаётся элемент "якобы" трёхмерного массива, как так? И координата ['KolRabMesto'] это как бы имя строки, должна идти первой... непонятненько...то есть, повторюсь "как бы" двумерный - а эху передаётся элемент "якобы" трёхмерного массива, как так? И координата ['KolRabMesto'] это как бы имя строки, должна идти первой... непонятненько...

Код:
echo ($Vuvod[$i]['KolRabMesto'][$k]);

массив был объявлен, как
array(
"Rab"=>range(1,100),
"KolRabMesto"=>range(1,100),
"TimeCritical"=>0);

$i,$k - это переменные цикла.
$PopRab = array("Rab"=>range(1,100), "KolRabMesto"=>range(1,100), "TimeCritical"=>0);
Мну нужно было создать массив PopRab c элементами массива Rab, RolRabMesto и TimeCritikal-это переменная, которая относится к этому массиву. Так как я ее начальное значение незнаю, то привоил ноль.
Т.е. тот же массив на языке Delphi выглядит так:
Код:
Type PopRab=Record
Rab: array[1..55] of byte;
KolRabMesto: array [1..8] of byte;
TimeCritical:real;
end;
var
MasPopRab: array[1..100] of PopRab;

возможно что я неправилно описал структуру массива, т.к. я не знаю всех тонкостей php
Неизвестный
26.03.2012, 16:07
общий
26.03.2012, 16:11
Кстати, ругается на эту строчку
Код:
session_register("RazmerPop", "nKros", "nMut", "PopRab", "MasPopRab", "Vuvod", "SaveP"); 

Deprecated: Function session_register() is deprecated in
а, понял, значит все таки не дают использовать session_register.
Неизвестный
26.03.2012, 16:29
общий
26.03.2012, 16:37
Сейчас в функциях выводит просто слово ArrayArrayArrayArrayArray, после того как добавил сессии. Хоть что то ....
Посмотрел значения. При нажатию на первой кнопке то выводит значение. Как делаешь вывод echo в функции, так пустота. Сесси добавил.
Неизвестный
26.03.2012, 16:42
общий
Код:
function SavePop() {

for($i=1;$i<$_SESSION['RazmerPop'];$i++)
$_SESSION['SaveP']=$_SESSION['MasPopRab'][$i]['Rab'];
echo'='.$_SESSION['SaveP'];
}

$_SESSION['SaveP'][$i] - то выводит пустоту.
если написать $_SESSION['SaveP'][$i] - то выводит последнюю цифру присвоенного значения массива. Видимо все таки я неправильно определил структуру массивов и из за этого неправильно все выводит.
давно
Старший Модератор
312929
1973
27.03.2012, 09:45
общий
27.03.2012, 09:54
Ещё нужно учитывать некоторые различия между PHP и Delphi.

Во-первых, в Delphi (как и в других "обычных" языках - C/C++, Basic и т.п.) глобальные переменные, находящиеся вне процедуры/функции, доступны внутри неё (если только внутри не определены локальные переменные с тем же именем). В PHP это не так - в нём (как и в других "скриптовых" языках - JavaScript, Perl и т.п.) переменные можно использовать без объявления, и все переменные внутри функции считаются локальными (внутренними), даже если использовать имена глобальных переменных. Для доступа к внешним переменным изнутри функции есть три способа: либо передать через параметр по ссылке аналогично var в Delphi (например, Krosover(&$MasPopRab)), либо обратиться к ней через суперглобальный массив $GLOBALS, содержащий все глобальные переменные (например, $GLOBALS['MasPopRab'] - то же, что глобальная переменная $MasPopRab), либо указать её внутри функции в инструкции globals (например, globals $MasPopRab;). В данном случае рекомендую последний вариант.

Во-вторых, в Delphi различают процедуры и функции: первые не возвращают значения, вторые - возвращают, причём это значение нужно присвоить переменной, имя которой совпадает с именем функции. В PHP function может быть и процедурой, и функцией, точнее, это функция, которая не обязательно возвращает значение. Возвращаемое значение при этом не присваевается какой-то переменной, а помещается в инструкцию return (например, return $p;, а не $proverka=$p;).

В-третьих, в PHP нет прямого аналога структурному типу Delphi (объявляемому с помощью record). Можно использовать классы (например, class PopRab {var Rab; var KolRabMesto; var TimeCritical; }), либо ассоциативные массивы (как в данном коде - array("Rab"=>range(1,65), "KolRabMesto"=>range(1,8), "TimeCritical"=>0)). В любом случае, если элемент объекта класса или ассоциативного массива должен быть массивом определённой длины, это нужно как-то указать при его создании, потому что по умолчанию он будет пустым.
давно
Старший Модератор
312929
1973
27.03.2012, 09:52
общий
Ещё по поводу сессий - вместо session_register можно в конце скрипта ставить $_SESSION = compact("RazmerPop", "nKros", "nMut", "PopRab", "MasPopRab", "Vuvod", "SaveP");, а в начале - extract($_SESSION, EXTR_OVERWRITE);. Первая функция упаковывает переменные с перечисленными именами в ассоциативный массив, а вторая - распаковывает этот массив обратно в переменные.
Неизвестный
27.03.2012, 11:19
общий
Адресаты:
Спасибо. Вы мне очень помогли.
давно
Старший Модератор
312929
1973
28.03.2012, 15:54
общий
это ответ
Здравствуйте, novij2011!

В первом приближении Ваша программа на PHP может выглядеть примерно так:
[code lang=php]<?php
session_start();

global $RazmerPop, $RazmerPopTek, $nKros, $nMut, $PopRab, $MasPopRab, $Vyvod, $SaveP;

$RazmerPop = intval($_POST['RazmerPop']);
$nKros = intval($_POST['nKros']);
$nMut = intval($_POST['nMut']);

extract($_SESSION, EXTR_OVERWRITE);

echo "
<form style='MARGIN: 0px' method=post action='popul.php'>
<table class='tableTable' border=0 cellSpacing=0 cellPadding=0>
<tbody class='tableBody'>
<tr class='tableRow tableRowEven'>
<td><div class='b1'>Размер популяции</div> </td>
<td><div class='b1'><INPUT NAME='RazmerPop' VALUE='$RazmerPop' size=4></div></td>
</tr>
<tr class='tableRow tableRowEven'>
<td><div class='b1'>Мутация (раз)</div> </td>
<td><div class='b1'><INPUT NAME='nMut' VALUE='$nMut' size=4></div></td>
</tr>
<tr class='tableRow tableRowEven'>
<td><div class='b1'>Кроссовер (раз)</div> </td>
<td><div class='b1'><INPUT NAME='nKros' VALUE='$nKros' size=4></div></td>
</tr>
<tr class='tableRow tableRowEven'>
<td class='button1'><div class='b1'><INPUT class='button blue' TYPE=submit NAME='submitButtonCreate' VALUE='Cоздать'></div></td>
<td class='button1'><div class='b1'><INPUT class='button blue' TYPE=submit NAME='submitButtonSave' VALUE='Генерировать'></div></td>
</tr>
</tbody>
</table>
</form>";

function SavePop()
{
global $RazmerPop, $MasPopRab, $SaveP;
for ($i=0; $i<$RazmerPop; $i++)
$SaveP[$i] = $MasPopRab[$i];
}

function Proverka($poz)
{
global $MasPopRab;
$p = true;
for ($t=0; $t<8; $t++)
$p = $p AND ($MasPopRab[$poz]['KolRabMesto'][$t]!=0);
return $p;
}

// Операция кроссовер
function Krosover()
{
global $RazmerPop, $RazmerPopTek, $MasPopRab;
$RazmerPopTek = $RazmerPop;
$NomPop = range(0, $RazmerPop-1);
shuffle($NomPop);
for ($j=0; $j<$nKos; $j++)
{
while ($NomPop) // сдесь квадратные скобки
{
$k1 = array_shift($NomPop);
$k2 = array_shift($NomPop);
do
{
$d = rand(1, 64);
// Новый вид 1
$RazmerPopTek++;
$MasPopRab[$RazmerPopTek]['Rab'] = array_merge(array_slice($MasPopRab[$k1]['Rab'],0,$d-1), array_slice($MasPopRab[$k2]['Rab'],$d));
// Новый вид 2
$RazmerPopTek++;
$MasPopRab[$RazmerPopTek]['Rab'] = array_merge(array_slice($MasPopRab[$k2]['Rab'],0,$d-1), array_slice($MasPopRab[$k1]['Rab'],$d));
if (Proverka($RazmerPopTek-1) AND Proverka($RazmerPopTek)) break;
else
{
$RazmerPopTek -= 2;
array_push($NomPop, $k1, $k2);
}
} while (true);
}
}
}

// Операция мутации
function MutaGen()
{
global $RazmerPopTek, $nMut, $MasPopRab;
for ($j=0; $j<$nMut; $j++)
{
$nom = rand(0, $RazmerPopTek-1);
do
{
$RazmerPopTek++;
$i = Rand(0, 64);
do $k = rand(1, 9);
while ($k<>$MasPopRab[$nom]['Rab'][$i] AND $MasPopRab[$nom]['KolRabMesto'][$k]>1);
$MasPopRab[$RazmerPopTek] = $MasPopRab[$nom];
$MasPopRab[$RazmerPopTek]['Rab'][$i] = $k;
if (Proverka($RazmerPopTek)) break;
else $RazmerPopTek -= 2;
} while (true);
}
}

// Отборка особей
function SortPop()
{
global $RazmerPopTek, $MasPopRab;
for ($i=0; $i<$RazmerPopTek-1; $i++)
for ($k=0; $k<$RazmerPopTek-1; $k++)
if ($MasPopRab[$k]['TimeCritical']>$MasPopRab[$k+1]['TimeCritical'])
{
$A = $MasPopRab[$k];
$MasPopRab[$k] = $MasPopRab[$k+1];
$MasPopRab[$k+1] = $A;
}
}

function SortVyvod()
{
global $v, $Vyvod;
for ($i=0; $i<$v-1; $i++)
for ($k=0; $k<$v-1; $k++)
if ($Vyvod[$k]['TimeCritical']>$Vyvod[$k+1]['TimeCritical'])
{
$A = $Vyvod[$k];
$Vyvod[$k]= $Vyvod[$k+1];
$Vyvod[$k+1]= $A;
}
for ($i=0; $i<$v-1; $i++)
{
for ($t=0; $t<8; $t++)
echo $Vyvod[$i]['KolRabMesto'][$t];
echo "
";
}
}

function Ostanov()
{
global $RazmerPop, $MasPopRab;
for ($i=0; $i<RazmerPop; $i++)
if ($SaveP[$i]['TimeCritical']!=$MasPopRab[$i]['TimeCritical']) return false;
return true;
}

if (!empty($_POST['submitButtonCreate']) AND isset($_POST['submitButtonCreate']))
{
$PopRab = array("Rab"=>range(1,65), "KolRabMesto"=>range(1,8), "TimeCritical"=>0);
$MasPopRab = array($PopRab);
$SaveP = array($PopRab);
$Vyvod = array($PopRab);
for ($i=0; $i<$RazmerPop; $i++)
{
for ($j=0; $j<65; $j++)
echo $MasPopRab[$i]['Rab'][$j] = rand(1,9);
echo "
";
}
}
// Генетический алгоритм
elseif (!empty($_POST['submitButtonSave']) AND isset($_POST['submitButtonSave']))
{
for ($v=0; Ostanov(); $v++)
{
SavePop();
Krosover();
MutaGen();
SortPop();
$Vyvod[$v] = $MasPopRab[1];
}
SortVyvod();
}

$_SESSION = compact('RazmerPopTek', 'MasPopRab', 'SaveP', 'Vyvod');
?>[/code]
Если что-то неясно, спрашивайте в минифоруме. Удачи.
Неизвестный
29.03.2012, 21:33
общий
29.03.2012, 21:46
Адресаты:
Целый час убирал цифры из скопированного текста программы в теге code.
Что то кнопочка генерировать выдает ошибки о ненайденных переменных, но дойдя то этой строчки
Код:
if ($SaveP[$i]['TimeCritical']!=$MasPopRab[$i]['TimeCritical']) 

у меня браузер просто завис намертво.
Notice: Use of undefined constant RazmerPop - assumed 'RazmerPop' in
function Ostanov() {
global $RazmerPop, $MasPopRab;
for ($i=0; $i<$RazmerPop; $i++)
/*if ($SaveP[$i]['TimeCritical']!=$MasPopRab[$i]['TimeCritical']) return false;
return true; }*/

Код:
 $p = $p AND ($MasPopRab[$poz]['KolRabMesto'][$t]!=0); //Undefined index: KolRabMesto in 
if ($MasPopRab[$k]['TimeCritical']>$MasPopRab[$k+1]['TimeCritical']) {
// Notice: Undefined index: TimeCritical in C:\apache\localhost\www\popul.php on line 81
а в самом коде непонятно только вот этот код:
Код:
array_merge(array_slice
shuffle($NomPop);
array_push

особенно оператор shuffle

Неизвестный
29.03.2012, 21:35
общий
Адресаты:
и спасибо за программу, хотя и не до конца рабочую
давно
Старший Модератор
312929
1973
30.03.2012, 08:15
общий
у меня браузер просто завис намертво

Там опечатка в коде: в функции Ostanov в цикле for вместо RazmerPop должно быть $RazmerPop (в PHP имена всех переменных должны начинаться со знака $, иначе они будут считаться константами).
Undefined index

Насколько я понял, в массиве $MasPopRab некоторые строчки могут не содержать элементы KolRabMesto и TimeCritical (только самая первая содержит их гарантированно). Проверьте, всегда ли в новой строке массива создаются все необходимые элементы (в отличие от "обычных" языков программирования, в PHP элементы массива по умолчанию не создаются).

array_slice(array, offset, length) - возвращает length элементов массива array, начиная с позиции offset (offset > 0 - от начала массива, offset < 0 - от конца массива, первый элемент имеет позицию 0, последний -1)

array_merge - соединяет несколько массивов в один, добавляя следующий в конец предыдущего (для ассоциативных массивов элементы с одинаковым значением ключа не дублируются - остаётся только последний, если все индексы числовые, то все элементы сохраняются с перенумерацией)

shuffle - перемешивает элементы массива в случайном порядке

array_push - добавляет новые элементы в конец массива
Неизвестный
30.03.2012, 13:06
общий
Адресаты:
Проверьте, всегда ли в новой строке массива создаются все необходимые элементы

т.е. я так понимаю надо после каждой функции переменной присвать ноль?
давно
Старший Модератор
312929
1973
31.03.2012, 21:43
общий
т.е. я так понимаю надо после каждой функции переменной присвать ноль?

Не обязательно ноль, но первым использованием любой переменной или элемента массива должно быть присвоение значения. В данном конкретном случае имеется многомерный массив $MasPopRab, каждый его элемент ($MasPopRab[0], $MasPopRab[1] и т.д.) является массивом с элементами 'Rab', 'KolRabMesto' и 'TimeCritical', причём два первых в свою очередь также являются массивами. В "обычных" языках такой массив (как и любую переменную) полагается описать заранее (до любого использования), после чего он будет существовать и все его элементы будут иметь некоторые начальные значения (обычно нулевые). В PHP переменные заранее описывать не обязательно, они создаются "на ходу" при первой записи в них значения, причём создание массива вовсе не означает создания его отдельных элементов. То есть, например, элемент $MasPopRab[0]['KolRabMesto'] может уже существовать, но это не значит, что существуют, скажем, $MasPopRab[1]['KolRabMesto'] или $MasPopRab[2]['KolRabMesto'] (даже если уже есть $MasPopRab[1] и $MasPopRab[2]) - их нужно создать. В противном случае при обращении к ним будет как раз ошибка Undefined index.
Неизвестный
31.03.2012, 22:14
общий
Адресаты:
спасибо, понятно. Буду исправлять.
Форма ответа