static __inline__ void calc_bbox_sub_nodes(BBOX_TREE* bbox_tree, Uint32 sub_node, Uint32 in_mask, AABBOX* bbox) { Uint32 out_mask, result, idx; if (sub_node != NO_INDEX) { idx = bbox_tree->cur_intersect_type; result = check_aabb_in_frustum(bbox_tree->nodes[sub_node].bbox, bbox_tree->intersect[idx].frustum, in_mask, &out_mask); if (result == INSIDE) { VMin(bbox->bbmin, bbox->bbmin, bbox_tree->nodes[sub_node].bbox.bbmin); VMax(bbox->bbmax, bbox->bbmax, bbox_tree->nodes[sub_node].bbox.bbmax); } else { if (result == INTERSECT) { merge_dyn_items(bbox_tree, sub_node, out_mask, bbox); if ( (bbox_tree->nodes[sub_node].nodes[0] == NO_INDEX) && (bbox_tree->nodes[sub_node].nodes[1] == NO_INDEX)) merge_items(bbox_tree, sub_node, out_mask, bbox); else { calc_bbox_sub_nodes(bbox_tree, bbox_tree->nodes[sub_node].nodes[0], out_mask, bbox); calc_bbox_sub_nodes(bbox_tree, bbox_tree->nodes[sub_node].nodes[1], out_mask, bbox); } } } } }
void fp_tree::recombine_items(double minsupp, int max_nmb_attr) { // computes the density for all items and // sort items by attribute and interval std::vector<fp_item *> items = m_item_dir->get_items(); typedef std::vector<std::pair<fp_item*, double> > t_item_vec; typedef std::map<int, t_item_vec* > t_item_map; // id ->item1->item2->item3... t_item_map item_map; for (std::vector<fp_item *>::iterator it = items.begin(); it != items.end(); it++) { fp_item* item = (*it); // ignore items with a frequency of zero // if (item->get_freq() > 0) { t_item_map::iterator map_it = item_map.find(item->get_id()); if (map_it == item_map.end()) { t_item_vec* items = new t_item_vec(); items->push_back( std::make_pair(item, item->get_density()) ); item_map.insert( std::make_pair(item->get_id(), items) ); } else { // sort item into item_list t_item_vec* items = map_it->second; t_item_vec::iterator items_it = items->begin(); while(items_it != items->end() && items_it->first->get_min() < item->get_min()) items_it++; if (items_it == items->end()) items->push_back(std::make_pair(item, item->get_density())); else items->insert( ++items_it, std::make_pair(item, item->get_density()) ); } } } #ifdef FPP_DEBUG for (t_item_map::iterator map_it = item_map.begin(); map_it != item_map.end(); map_it++) { std::cout << "XXXCurr_item_vec: ((" << map_it->first << "))\n\t"; std::vector<std::pair<fp_item*, double> >* curr_item_vec = map_it->second; for(t_item_vec::iterator pit = curr_item_vec->begin(); pit != curr_item_vec->end(); pit++) std::cout << "[[" << pit->first << " dens: " << pit->second << " freq: " << pit->first->get_freq() << "]]\n\t"; std::cout << std::endl; } #endif // as long as the given max_nmb_attr number is reached // find the node with the maximum density per attribute // merge items as long as the minsupp is reached for (t_item_map::iterator map_it = item_map.begin(); map_it != item_map.end(); map_it++) { int curr_item_nmb = 0; std::vector<std::pair<fp_item*, double> >* curr_item_vec = map_it->second; // cleanup vector from items with a frequency of zero // reason: the item was dropped since the last process if (curr_item_vec->size() > 1) for (int i = 0; i < curr_item_vec->size(); i++ ) { if ( (*curr_item_vec)[i].first->get_freq() == 0 ) {// drop it (*curr_item_vec).erase((*curr_item_vec).begin() + i); i--; } } // process each attribute as long as at least the definied number of items was created while (curr_item_vec->size() > 1 // we need at least two items two combine && curr_item_nmb < max_nmb_attr) { // find max_dens_item unsigned int max_idx = 0; for(unsigned int i = 0; i < curr_item_vec->size(); i++) { if ( (*curr_item_vec)[max_idx].second < (*curr_item_vec)[i].second) max_idx = i; } int i = 0; while ( (*curr_item_vec)[max_idx].first->get_freq() < minsupp && (*curr_item_vec).size() > 1) { #ifdef FPP_DEBUG std::cout << "Curr_item_vec: ((" << i++ << "))\n\t"; for(t_item_vec::iterator pit = curr_item_vec->begin(); pit != curr_item_vec->end(); pit++) std::cout << "[[" << pit->first << " dens: " << pit->second << " freq: " << pit->first->get_freq() << "]]\n\t"; std::cout << std::endl; #endif // Itemmerge Rules // merge with left or right children? fp_item* merge_item1 = (*curr_item_vec)[max_idx].first; fp_item* merge_item2; double dens_neigh = 0; // left neighbor if (max_idx > 0 ) { merge_item2 =(*curr_item_vec)[max_idx-1].first; dens_neigh = (*curr_item_vec)[max_idx-1].second; } // right neighbor if (max_idx < curr_item_vec->size()-1) { if ((*curr_item_vec)[max_idx+1].second > dens_neigh) { merge_item2 = (*curr_item_vec)[max_idx+1].first; (*curr_item_vec).erase((*curr_item_vec).begin() + max_idx + 1); } else if (max_idx != 0 ) { (*curr_item_vec).erase((*curr_item_vec).begin() + max_idx - 1); max_idx--; } } // std::cout << merge_item1 << "\t" << merge_item2 << std::endl; if (merge_item1->get_min() < merge_item2->get_min()) (*curr_item_vec)[max_idx].first = merge_items(merge_item1, merge_item2); else (*curr_item_vec)[max_idx].first = merge_items(merge_item2, merge_item1); } curr_item_nmb++; } } }