& quot; Невозможно получить возвращаемое значение генератора, который не возвратил & quot; php backtracking

Я пытаюсь вернуться, чтобы решить проблему, но я получаю эту ошибку:

Ошибка: genator не вернулся

Я представлю основную проблему, которую должно решить программное обеспечение:

Я пытался создать программное обеспечение для больницы, это
Программное обеспечение должно составлять расписание с врачами на каждый день. каждый
в день должно быть 5 назначенных врачей, один по специальности «травма»,
другой для «ucr» и другой для «box13».

Перед назначением врачей пользователь должен ввести количество лунок
каждый тип, который доктор может сделать в этом месяце. Итак, я знаю, сколько «травмы»,
У «ucr» или «box13» в этом месяце был доктор.

Ааа! Еще одна вещь, которую вы не можете назначить доктору два дня подряд.

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

function bt($ps){
if($ps->is_solution()){
return $ps->get_solution();
}
else{
yield from $ps->successors();
}
}


class Briker_vc_PS{
public function __construct( $decisiones, $diasTotalFinal, $fechaInicio, $box13, $ucr, $trauma, $numGuardiasAsig){
$this->decisiones= $decisiones;
$this->diasTotalFinal = $diasTotalFinal;
$this->fechaInicio = $fechaInicio;
$this->box13 = $box13;
$this->ucr = $ucr;
$this->trauma = $trauma;
$this->numGuardiasAsig = $numGuardiasAsig;
}

public function is_solution(){

return $this->numGuardiasAsig == $this->diasTotalFinal*5;
}

public function get_solution(){
return $this->decisiones;
}

public function state(){
return $this->decisiones[$this->fechaInicio];
}

public function  successors(){
if( array_key_exists( $this->fechaInicio, $this->decisiones) == false ){
$this->decisiones[$this->fechaInicio] = [];
}

if( array_key_exists( 'ids', $this->decisiones[$this->fechaInicio]) == false ){
$this->decisiones[$this->fechaInicio]['ids'] = [];
}


if( array_key_exists( $this->fechaInicio ,$this->decisiones) and array_key_exists( 'box13' ,$this->decisiones) and array_key_exists( 'trauma' ,$this->decisiones) and array_key_exists( 'ucr' ,$this->decisiones)){
if( (count($this->decisiones['trauma'])==1) and (count($this->decisiones['ucr'])==2) and (count($this->decisiones['box13'])==2) ){
$this->fechaInicio = date("Y-m-d",strtotime($this->fechaInicio." +1 day"));
$this->decisiones[$this->fechaInicio]['date'] = $this->fechaInicio;
}
}

$anterior = date("Y-m-d",strtotime($this->fechaInicio." -1 day"));

$Lista=[];

if( array_key_exists( 'trauma' ,$this->decisiones) == false ){
foreach($this->trauma as $key => $val){
if( (in_array($key, $this->decisiones[$this->fechaInicio]['ids']) == false) and (in_array($key, $this->decisiones[$anterior]['ids']) == false) ){
$decisions= $this->decisiones;

$decisions[$this->fechaInicio]['trauma'] = [$key];
$auxtra= $this->trauma;

if($auxtra[$key] -1 == 0){
unset($auxtra[$key]);
}else{
$auxtra[$key] = $auxtra[$key] -1;
}

$num = $this->numGuardiasAsig +1 ;

$decisions[$this->fechaInicio]['ids'][] = $key;

yield from bt(new Briker_vc_PS( $decisions, $this->diasTotalFinal, $this->fechaInicio, $this->box13, $this->ucr, $auxtra, $num));

}
}
}

if( (array_key_exists( 'box13' ,$this->decisiones) == false) or (count($this->decisiones['box13'])<2) ){
foreach($this->box13 as $key => $val){
if( (in_array($key, $this->decisiones[$this->fechaInicio]['ids']) == false) and (in_array($key, $this->decisiones[$anterior]['ids']) == false) ){
$decisions= $this->decisiones;

if(array_key_exists( 'box13' ,$this->decisiones) == false){
$decisions[$this->fechaInicio]['box13'] = array();
}

$decisions[$this->fechaInicio]['box13'][] = $key;
$auxbox13= $this->box13;

if($auxbox13[$key] -1 == 0){
unset($auxbox13[$key]);
}else{
$auxbox13[$key] = $auxbox13[$key] -1;
}

$num = $this->numGuardiasAsig +1 ;

$decisions[$this->fechaInicio]['ids'][] = $key;

yield from bt( new Briker_vc_PS( $decisions, $this->diasTotalFinal, $this->fechaInicio, $auxbox13, $this->ucr, $this->trauma, $num));

}
}
}

if( (array_key_exists( 'ucr' ,$this->decisiones) == false) or (count($this->decisiones['ucr'])<2) ){
foreach($this->ucr as $key => $val){
if( (in_array($key, $this->decisiones[$this->fechaInicio]['ids']) == false) and (in_array($key, $this->decisiones[$anterior]['ids']) == false) ){
$decisions= $this->decisiones;

if(array_key_exists( 'ucr' ,$this->decisiones) == false){
$decisions[$this->fechaInicio]['ucr'] = array();
}

$decisions[$this->fechaInicio]['ucr'][] = $key;
$auxucr= $this->ucr;

if($auxucr[$key] -1 == 0){
unset($auxucr[$key]);
}else{
$auxucr[$key] = $auxucr[$key] -1;
}

$decisions[$this->fechaInicio]['ids'][] = $key;

$num = $this->numGuardiasAsig +1 ;

yield from bt(new Briker_vc_PS( $decisions, $this->diasTotalFinal, $this->fechaInicio, $this->box13, $auxucr, $this->trauma, $num));

}
}
}

}

protected $GuardiasMedico;
protected $decisiones;

}

И это основная программа

      $month = $_REQUEST['mes'];
$year = $_REQUEST['any'];

$fecha_inicio = "01-".$month."-".$year;


// fisrt i get the number of "trauma", "ucr" and "box13" for each doctor
// And i create a array with it with key the doctor_id

$db = new SQLite3($dbname);

$result = $db->query('SELECT m.id, m.nombre, m.apellido, mgm.ucr, mgm.trauma, mgm.box13 FROM medico AS m INNER JOIN MedicoGuardiaMes AS mgm ON m.id = mgm.doctor_id WHERE m.borrado = 0 AND mgm.mes = '.$month.' AND mgm.any = '.$year);


$box13 = [];
$ucr = [];
$trauma = [];

while($res = $result->fetchArray()){

$box13[$res['id']] =  $res['box13'];
$ucr[$res['id']] =  $res['ucr'];
$trauma[$res['id']] =  $res['trauma'];

}

// I create the solution array and add the last day from the previous month

$dataBaseDecisiones = [];

$anterior = date("Y-m-d",strtotime($fecha_inicio." -1 day"));

$dataBaseDecisiones[$anterior] = [];
$dataBaseDecisiones[$anterior]['ids'] = [];

$diasTotalFinal=cal_days_in_month(CAL_GREGORIAN, $month, $year);


// Finally I create the initial object and starts the backtracking


$initial_ps = new Briker_vc_PS($dataBaseDecisiones, $diasTotalFinal, $fecha_inicio, $box13, $ucr, $trauma, $numGuardiasAsig);

var_dump(  bt($initial_ps)->getReturn() );

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

-1

Решение

Проблема, о которой сообщают, происходит из-за последней строки в вашем коде:

bt($initial_ps)->getReturn();

когда bt выполняет else часть выполняет рекурсивный поиск, пока не будет returnи тогда это доходность это значение. Но это не заканчивает результаты итератора, и это полученное значение не считается итератором вернуть значение. Так getReturn() вызывает исключение, которое вы получили.

Вы не объясняете, что вы намереваетесь получить в качестве выхода в этом var_dump, Если вы хотите вывести все полученные результаты, то сначала соберите все эти результаты, например, с помощью iterator_to_array:

$iter = bt($initial_ps);
print_r(iterator_to_array($iter));

И только тогда вы сможете выполнить:

print_r($iter->getReturn());
0

Другие решения

Других решений пока нет …