Recommend this page to a friend! |
PHP Matrix Similarity | > | All threads | > | Problems | > | (Un) Subscribe thread alerts |
|
Dave Smith - 2015-05-29 02:36:00
I played around with this a bit to figure out what it does.
The getAllConnexion property locates all items of the same value within a grid that are connected from the specified starting point. The script will stop execution with a fatal error if the xdebug.max_nesting_level is exceeded, which on my installation defaults to 100. Looks like you will need to count your recursions and return the results if the xdebug.max_nesting_level is reached. The getRegularConnexion property locates the first occurrence of connected items if they are at least as long as the supplied max value. Is it supposed to find connections up to the max? For example, if the max is 5, should it return connections of 2, 3, and 4 like values as well as 5. If so, I only saw connection results if there where at least the supplied max value. Is it supposed to find all connections using the supplied directions? If so, my results only returned the first connection even if more connections where valid. Dave
Ghali Ahmed - 2015-05-29 14:38:02 - In reply to message 1 from Dave Smith
Thank you Dave for this feedback
so "The script will stop execution with a fatal error if the xdebug.max_nesting_level is exceeded, which on my installation defaults to 100. Looks like you will need to count your recursions and return the results if the xdebug.max_nesting_level is reached." plz can you share your implemtation ? otherwise this is a very strange behaviour and i don't have any idea how to solve that (maybe the algorithm should be reviewed) "Is it supposed to find connections up to the max?" Exactly, when the max is reached the class return the found connexions if (count($result[$key]) == $max) { return $result[$key]; } cordially
Dave Smith - 2015-05-29 20:56:06 - In reply to message 2 from Ghali Ahmed
I didn't implement it, I just ran your demo.
The xdebug.max_nesting_level is set to prevent infinite recursions and is set to 100 nested levels by default, if the xdebug extension is compiled with php. xdebug is normally compiled with php and the setting can be increased or disabled in the php.ini file. I have just ran some tests... For testing purposes, I increased the tile dimensions to 40x40 and selected the center tile 20x20, so that the nesting level limit can be reached more often. max_nesting_level problem... I tried to find a way to test against the current nested level, but couldn't find a way to get the current nested level, so if anyone knows how to test this against the stack, let me know. I wound up deciding to just disable it and enable it again when completed. The problem with this approach is that it will run until the max memory usage is reached, so eventually you will need to get some memory checks in there. The solution... 1) I added a new private class property to hold the current level private $maxNest; 2) I disabled max_nesting_level in the constructor __construct $this->maxNest = ini_set('xdebug.max_nesting_level',0); 3) If max_nesting_label was originally enabled, I set it back so that our class plays nice with others, using __destruct. public function __destruct(){ if( !empty($this->maxNest) ){ ini_set('xdebug.max_nesting_level',$this->maxNest); } } I will discuss the other problem in another message. Dave
Dave Smith - 2015-05-29 21:30:01 - In reply to message 2 from Ghali Ahmed
The code you provided is the start of the problem...
if (count($result[$key]) == $max) { return $result[$key]; } This is inside the loop checking for matches in a particular direction, which is nested in the loop changing directions. What is happening is that the first time a connection which reaches the defined max is found, it is dropping out of the loops and just returning that single match. solution... If we change that code to if (count($result[$key]) == $max) { break; } we get a multi-dimensional array which contains the direction and all matches within that direction up to the max. now we need to flatten out the array by adding this before... return $return; $flat = []; foreach( $result as $direction ){ foreach( $direction as $value ){ if( !empty($value) ){ if( !in_array($value,$flat) ){ $flat[] = $value; } } } } $result = $flat; What we get is all connections in designated directions that are the max length. Dave
Ghali Ahmed - 2015-05-30 20:13:48 - In reply to message 4 from Dave Smith
Done!
Thank you so much
Dave Smith - 2015-05-30 20:47:13 - In reply to message 5 from Ghali Ahmed
The flatten process is in the wrong place. If you only want to return one result, then the original code would be better, however if you want to return all directions you have to stay in the loop all the way through. Here is the method which returns multiple results...
public function getRegularConnexion($m, $n, $max) { $result = []; $len = count($this->tile); foreach ($this->directions as $key => $direction) { if (!isset($result[$key])) { $result[$key] = []; } for ($i = 0; $i < $len; $i++) { $iTarget = $m + $i*$direction[0]; $jTarget = $n + $i*$direction[1]; if ($this->tile[$m][$n] != @$this->tile[$iTarget][$jTarget]) { break; } else { $result[$key][] = "$iTarget:$jTarget"; if (count($result[$key]) == $max) { //return $result[$key]; break; } } } $result[$key] = (count($result[$key]) >=$max)?$result[$key]:[]; }; $flat = []; foreach( $result as $direction ){ foreach( $direction as $value ){ if( !empty($value) ){ if( !in_array($value,$flat) ){ $flat[] = $value; } } } } $result = $flat; return $result; } Dave
Ghali Ahmed - 2015-05-31 09:24:58 - In reply to message 6 from Dave Smith
ok now the class is edited to perform both multiple and single direction results.
|
info at phpclasses dot org
.