예제 #1
0
 void clear() {
   eigen_vector_query.clear();
   spt_query.clear();
 }
예제 #2
0
void graph_wo_index::get_diff_eigen_score(eigen_vector_query_diff& diff) const {
  diff.clear();  // tmp_diff + swap is better ?

  for (eigen_vector_query_mixed::const_iterator query_it
           = eigen_scores_.begin();
       query_it != eigen_scores_.end(); ++query_it) {
    const preset_query& query = query_it->first;
    const eigen_vector_mixed& model = query_it->second;

    double dist = 0;
    for (eigen_vector_mixed::const_iterator it = model.begin();
         it != model.end(); ++it) {
      if (it->second.out_degree_num == 0) {
        dist += it->second.score;
      }
    }

    unordered_set<node_id_t> unmatched_nodes;

    uint64_t new_node_num = 0;
    double dist_from_new_node = 0;
    for (node_info_map::const_iterator node_it = local_nodes_.begin();
         node_it != local_nodes_.end(); ++node_it) {
      if (model.count(node_it->first) == 0) {
        if (!is_matched_to_query(query.node_query, node_it->second.property)) {
          unmatched_nodes.insert(node_it->first);
          continue;
        }
        dist_from_new_node += 1.0;
        ++new_node_num;
      }
    }
    dist += dist_from_new_node;

    if (model.size() + new_node_num > 0) {
      dist /= (model.size() + new_node_num);
    }

    eigen_vector_diff& qdiff = diff[query];

    for (node_info_map::const_iterator node_it = local_nodes_.begin();
         node_it != local_nodes_.end(); ++node_it) {
      if (unmatched_nodes.count(node_it->first)) {
        continue;
      }
      if (!is_matched_to_query(query.node_query, node_it->second.property)) {
        unmatched_nodes.insert(node_it->first);
        continue;
      }

      const std::vector<edge_id_t>& in_edges = node_it->second.in_edges;
      double score = 0;
      for (size_t i = 0; i < in_edges.size(); ++i) {
        if (unmatched_nodes.count(in_edges[i])) {
          continue;
        }
        edge_info_map::const_iterator edge_it = local_edges_.find(in_edges[i]);
        if (edge_it == local_edges_.end()) {
          continue;
        }

        const node_id_t src = edge_it->second.src;
        if (unmatched_nodes.count(src)) {
          continue;
        }
        if (!is_matched_to_query(query.edge_query, edge_it->second.p)) {
          continue;
        }

        eigen_vector_mixed::const_iterator it = model.find(edge_it->second.src);
        if (it == model.end()) {
          continue;
        }
        if (it->second.out_degree_num != 0) {
          // TODO(beam2d) it->second.score > 0 should indicate
          // it->second.out_degree_num
          score += it->second.score / it->second.out_degree_num;
        }
      }

      eigen_vector_info ei;
      ei.score = config_.alpha * score + 1 - config_.alpha
          + config_.alpha * dist;

      if (is_empty_query(query)) {
        ei.out_degree_num = node_it->second.out_edges.size();
      } else {
        uint64_t out_degree = 0;
        for (size_t i = 0; i < node_it->second.out_edges.size(); ++i) {
          const edge_info_map::const_iterator edge_it
              = local_edges_.find(node_it->second.out_edges[i]);
          const edge_info& edge = edge_it->second;
          if (unmatched_nodes.count(edge.tgt)) {
            continue;
          }
          if (!is_node_matched_to_query(query, edge.tgt)) {
            unmatched_nodes.insert(edge.tgt);
            continue;
          }
          if (!is_matched_to_query(query.edge_query, edge.p)) {
            continue;
          }
          ++out_degree;
        }
        ei.out_degree_num = out_degree;
      }

      qdiff[node_it->first] = ei;
    }
  }
}