Проблема с операциями удаления для KDTree в Python из C кода - PullRequest
1 голос
/ 13 июля 2020

Я пытаюсь преобразовать свой код C в Python, где я реализовал структуру KDTree в контексте алгоритма Парето.

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

/*** Find the root of tree with max or min (=1) coordinate in dimension dim ***/
KD_TREE* KD_find_opt(KD_TREE *tree, int dim, int depth, KD_TREE *opt,
                     int min, int *value, int *depth_opt)
{ int val = (*tree)->key[dim];
  if ((min && *value > val) || (!min && *value < val) )
  { opt = tree;
    *value = val;
    *depth_opt = depth;
  }
  if ((*tree)->L != NULL)
    opt = KD_find_opt(&(*tree)->L, dim, depth+1, opt, min, value, depth_opt);
  if ((*tree)->r != NULL)
    opt = KD_find_opt(&(*tree)->r, dim, depth+1, opt, min, value, depth_opt);
  return opt;
}

/********* Remove the root node from a (sub-)KD-tree knowing its depth ********/  
void KD_delete(KD_TREE *root, size_t info_size, int depth)
{ if ( (*root)->L == NULL && (*root)->r == NULL )
  { free( (*root)->info );
    free(*root);
    *root = NULL;
    return;
  }

  KD_TREE *replacing;              /* Node that will replace the removed node */
  int val_repl;
  int depth_repl;
  if ((*root)->L != NULL)  /* Find replacing node with max coordinate at left */
  { val_repl = INT_MIN;
    replacing = KD_find_opt(&(*root)->L, depth%K, depth+1, NULL,
                            0, &val_repl, &depth_repl);
  }
  else                /* Find replacing node with minimal coordinate at right */
  { val_repl = INT_MAX;
    replacing = KD_find_opt(&(*root)->r, depth%K, depth+1, NULL,
                            1, &val_repl, &depth_repl);
  }

  memcpy((*root)->key, (*replacing)->key, K*sizeof(int));
  INFO *tmp = (*root)->info; (*root)->info = (*replacing)->info;
  (*replacing)->info = tmp;
  KD_delete(replacing, info_size, depth_repl);
}
def kd_tree_find_opt(self, tree, dim, depth, opt, minimum, value, depth_opt):
        val = tree.key[dim]
        if (minimum and (value > val)) \
                or ((not minimum) and (value < val)):
            opt = tree
            value = val
            depth_opt = depth
        if tree.left:
            opt, value, depth_opt = self.kd_tree_find_opt(tree.left, dim, depth + 1,
                                        opt, minimum, value, depth_opt)
        if tree.right:
            opt, value, depth_opt = self.kd_tree_find_opt(tree.right, dim, depth + 1,
                                        opt, minimum, value, depth_opt)
        return opt, value, depth_opt

    def kd_tree_delete(self, root, depth):
        if (root.left is None) and (root.right is None):
            self.root = None
        else:
            if root.left:
                val_repl = float('-inf'); depth_repl = 0
                replacing, val_repl, depth_repl = self.kd_tree_find_opt(root.left, 
                        depth % K, depth + 1, None, 0, val_repl, depth_repl)
            else:
                val_repl = float('inf'); depth_repl = 0
                replacing, val_repl, depth_repl = self.kd_tree_find_opt(root.right, 
                        depth % K, depth + 1, None, 1, val_repl, depth_repl)

            root.key = replacing.key[:]
            root.info = replacing.info[:]
            kd_tree_delete(replacing, depth_repl)

Насколько я понимаю, похоже, есть существенная разница в способах управления памятью C и Python.

self. root = None не удаляет сам объект. Он просто присваивает self. root другое значение. Поскольку я был новичком в Python, я искал эффективный способ реализации операций удаления. Заранее спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...