bool MyGraphicsView::isPointVisible(QPointF p) { QPointF corner1, corner2, corner3, corner4; getFourViewportCornersInSceneCoordinates(&corner1, &corner2, &corner3, &corner4); QLineF boundary1(corner1, corner2); QLineF boundary2(corner2, corner3); QLineF boundary3(corner3, corner4); QLineF boundary4(corner4, corner1); return !(differentSidesOfLine(p, corner3, boundary1) || differentSidesOfLine(p, corner4, boundary2) || differentSidesOfLine(p, corner1, boundary3) || differentSidesOfLine(p, corner2, boundary4)); }
//This function assumes that the line does intersect with the viewport //boundary - i.e. one end of the line is in the viewport and one is not. QPointF MyGraphicsView::findIntersectionWithViewportBoundary(QLineF line) { QPointF c1, c2, c3, c4; getFourViewportCornersInSceneCoordinates(&c1, &c2, &c3, &c4); QLineF boundary1(c1, c2); QLineF boundary2(c2, c3); QLineF boundary3(c3, c4); QLineF boundary4(c4, c1); QPointF intersection; if (line.intersect(boundary1, &intersection) == QLineF::BoundedIntersection) return intersection; if (line.intersect(boundary2, &intersection) == QLineF::BoundedIntersection) return intersection; if (line.intersect(boundary3, &intersection) == QLineF::BoundedIntersection) return intersection; if (line.intersect(boundary4, &intersection) == QLineF::BoundedIntersection) return intersection; //The code should not get here, as the line should intersect with one of //the boundaries. return intersection; }
// implements our version of gal combine // compute a matching between blocks (greedily) // extend to partition // apply our refinements and tabu search void gal_combine::perform_gal_combine( PartitionConfig & config, graph_access & G) { //first greedily compute a matching of the partitions std::vector< std::unordered_map<PartitionID, unsigned> > counters(config.k); forall_nodes(G, node) { //boundary_pair bp; if(counters[G.getPartitionIndex(node)].find(G.getSecondPartitionIndex(node)) != counters[G.getPartitionIndex(node)].end()) { counters[G.getPartitionIndex(node)][G.getSecondPartitionIndex(node)] += 1; } else { counters[G.getPartitionIndex(node)][G.getSecondPartitionIndex(node)] = 1; } } endfor std::vector< PartitionID > permutation(config.k); for( unsigned i = 0; i < permutation.size(); i++) { permutation[i] = i; } random_functions::permutate_vector_good_small(permutation); std::vector<bool> rhs_matched(config.k, false); std::vector<PartitionID> bipartite_matching(config.k); for( unsigned i = 0; i < permutation.size(); i++) { PartitionID cur_partition = permutation[i]; PartitionID best_unassigned = config.k; NodeWeight best_value = 0; for( std::unordered_map<PartitionID, unsigned>::iterator it = counters[cur_partition].begin(); it != counters[cur_partition].end(); ++it) { if( rhs_matched[it->first] == false && it->second > best_value ) { best_unassigned = it->first; best_value = it->second; } } bipartite_matching[cur_partition] = best_unassigned; if( best_unassigned != config.k ) { rhs_matched[best_unassigned] = true; } } std::vector<bool> blocked_vertices(G.number_of_nodes(), false); forall_nodes(G, node) { if( bipartite_matching[G.getPartitionIndex(node)] == G.getSecondPartitionIndex(node) ){ blocked_vertices[node] = true; } else { // we will reassign this vertex since the partitions do not agree on it G.setPartitionIndex(node, config.k); } } endfor construct_partition cp; cp.construct_starting_from_partition( config, G ); refinement* refine = new mixed_refinement(); double real_epsilon = config.imbalance/100.0; double epsilon = random_functions::nextDouble(real_epsilon+0.005,real_epsilon+config.kabaE_internal_bal); PartitionConfig copy = config; copy.upper_bound_partition = (1+epsilon)*ceil(config.largest_graph_weight/(double)config.k); complete_boundary boundary(&G); boundary.build(); tabu_search ts; ts.perform_refinement( copy, G, boundary); //now obtain the quotient graph complete_boundary boundary2(&G); boundary2.build(); copy = config; copy.upper_bound_partition = (1+epsilon)*ceil(config.largest_graph_weight/(double)config.k); refine->perform_refinement( copy, G, boundary2); copy = config; cycle_refinement cr; cr.perform_refinement(config, G, boundary2); delete refine; }