«Невозможно получить возвращаемое значение генератора, который не возвратил» php backtracking - PullRequest
0 голосов
/ 24 августа 2018

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

Ошибка: генатор не вернулся

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

Я пытался создать программное обеспечение для больницы, это Программное обеспечение должно составлять расписание с врачами на каждый день. каждый в день должно быть 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() );

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

1 Ответ

0 голосов
/ 24 августа 2018

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

bt($initial_ps)->getReturn();

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

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

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

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

print_r($iter->getReturn());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...