I have kind of a tree structure outputted from another method in a format:
$tracks = [[1,4],[3,5],[2,3,5],[1,2],[2,4]];
Where top node is empty array and $tracks[0] = [1,4]
combines first two nodes (either 1
or 4
). This is not a binary tree as seen from $tracks[2] = [2,3,5]
which would mean that there are three possible nodes.
I want to find the first combination where numbers do not repeat (for example [1,3,5,2,4]
), so going through the whole tree is not necessary.
I have created a function, but ran into a problem which I cannot figure out how to solve:
$availableTracks = [[1,4],[3,5],[2,3,5],[1,2],[2,4]];
$availableTracks2 = [[1,4],[3,5],[2,3,5],[1],[2,4]];
/*
$pairedTracks = all tracks given
$currentPath = generated path
$level = which level in tree
$nodeElement = element position
$previousnode = which node it started from in current level
*/
function findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode){
if (in_array($pairedtracks[$level][$nodeElement],$currentPath)){
echo "[IN ARRAY]: Node element in current: ".$pairedtracks[$level][$nodeElement]." on level: ".$level;
echo "<br>";
echo "Node which level lowered from: ".$previousNode;
echo "<br>";
//Check if node element is in array
$maxLength = count($pairedtracks[$level]);
if ($nodeElement+1 == $maxLength){
//Current was final, return back up
$level -= 1;
// Go forward from previous
$previousNode += 1;
// Set new start node in recursive function
$nodeElement = $previousNode;
if ($nodeElement == count($pairedtracks[$level])){
//Check if node element is on the same length, then go back even more.
/*
At this point i realized that i'm going to need to keep track of too many previous iterations
*/
}
echo "Moving back up to level: ".$level.", starting iteration from: ".$nodeElement;
echo "<br>";
// Remove previously added element from that level!
array_splice($currentPath, $currentPath[count($currentPath)-1], 1);
return findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode);
}
else {
//More elements to follow
$nodeElement += 1;
return findBestPath($pairedtracks,$currentPath,$level,$nodeElement,$previousNode);
}
}
else {
//Was not in array, element can be added to current path
echo "Adding element to current path: ".$pairedtracks[$level][$nodeElement];
echo "<br>";
$currentPath[] = $pairedtracks[$level][$nodeElement];
//Check if path has finalized or check more
if (count($currentPath) == count($pairedtracks)){
//Search finished
return $currentPath;
}
else {
//Move downwards
$level += 1;
return findBestPath($pairedtracks,$currentPath,$level,0,$nodeElement);
}
}
}
$path = findBestPath($availableTracks2,[],0,0,0);
foreach ($path as &$value) {
echo $value." ";
}
It will work for availableTracks
, but runs into problems when it has to go back more than one level. I came to a conclusion that i'd need to keep more than a single previousnode
, but i'm certain that it should be possible to not keep it in memory, but just modify the length of array on each recursion accordinly. Unfortunately i couldn't figure out a way to do that and maybe someone can help me with that?