OutputIterator sloan_ordering(Graph& g, typename graph_traits<Graph>::vertex_descriptor s, typename graph_traits<Graph>::vertex_descriptor e, OutputIterator permutation, ColorMap color, DegreeMap degree, PriorityMap priority, Weight W1, Weight W2) { //typedef typename property_traits<DegreeMap>::value_type Degree; typedef typename property_traits<PriorityMap>::value_type Degree; typedef typename property_traits<ColorMap>::value_type ColorValue; typedef color_traits<ColorValue> Color; typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter; typedef typename graph_traits<Graph>::vertices_size_type size_type; typedef typename property_map<Graph, vertex_index_t>::const_type VertexID; //Creating a std-vector for storing the distance from the end vertex in it typename std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(g), 0); //Wrap a property_map_iterator around the std::iterator boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, g)); breadth_first_search (g, e, visitor ( make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) ) ); //Creating a property_map for the indices of a vertex typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, g); //Sets the color and priority to their initial status unsigned cdeg; typename graph_traits<Graph>::vertex_iterator ui, ui_end; for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) { put(color, *ui, Color::white()); cdeg=get(degree, *ui)+1; put(priority, *ui, W1*dist[index_map[*ui]]-W2*cdeg ); } //Priority list typedef indirect_cmp<PriorityMap, std::greater<Degree> > Compare; Compare comp(priority); std::list<Vertex> priority_list; //Some more declarations typename graph_traits<Graph>::out_edge_iterator ei, ei_end, ei2, ei2_end; Vertex u, v, w; put(color, s, Color::green()); //Sets the color of the starting vertex to gray priority_list.push_front(s); //Puts s into the priority_list while ( !priority_list.empty() ) { priority_list.sort(comp); //Orders the elements in the priority list in an ascending manner u = priority_list.front(); //Accesses the last element in the priority list priority_list.pop_front(); //Removes the last element in the priority list if(get(color, u) == Color::green() ) { //for-loop over all out-edges of vertex u for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { v = target(*ei, g); put( priority, v, get(priority, v) + W2 ); //updates the priority if (get(color, v) == Color::white() ) //test if the vertex is inactive { put(color, v, Color::green() ); //giving the vertex a preactive status priority_list.push_front(v); //writing the vertex in the priority_queue } } } //Here starts step 8 *permutation++ = u; //Puts u to the first position in the permutation-vector put(color, u, Color::black() ); //Gives u an inactive status //for loop over all the adjacent vertices of u for (boost::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei) { v = target(*ei, g); if (get(color, v) == Color::green() ) { //tests if the vertex is inactive put(color, v, Color::red() ); //giving the vertex an active status put(priority, v, get(priority, v)+W2); //updates the priority //for loop over alll adjacent vertices of v for (boost::tie(ei2, ei2_end) = out_edges(v, g); ei2 != ei2_end; ++ei2) { w = target(*ei2, g); if(get(color, w) != Color::black() ) { //tests if vertex is postactive put(priority, w, get(priority, w)+W2); //updates the priority if(get(color, w) == Color::white() ){ put(color, w, Color::green() ); // gives the vertex a preactive status priority_list.push_front(w); // puts the vertex into the priority queue } //end if } //end if } //end for } //end if } //end for } //end while return permutation; }
bool operator()(CorrespondenceMapFirstToSecond correspondence_map_1_to_2, CorrespondenceMapSecondToFirst correspondence_map_2_to_1, typename boost::graph_traits<Graph>::vertices_size_type subgraph_size) { typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; typedef typename boost::graph_traits<Graph>::edge_descriptor Edge; typedef std::pair<Edge, bool> EdgeInfo; typedef typename boost::property_map<Graph, boost::vertex_index_t>::type VertexIndexMap; typedef typename boost::property_map<Graph, boost::vertex_name_t>::type VertexNameMap; typedef typename boost::property_map<Graph, boost::edge_name_t>::type EdgeNameMap; if (subgraph_size != num_vertices(m_common_subgraph)) { return (true); } // Fill membership maps for both graphs typedef boost::shared_array_property_map<bool, VertexIndexMap> MembershipMap; MembershipMap membership_map1(num_vertices(m_graph1), get(boost::vertex_index, m_graph1)); MembershipMap membership_map2(num_vertices(m_graph2), get(boost::vertex_index, m_graph2)); boost::fill_membership_map<Graph>(m_graph1, correspondence_map_1_to_2, membership_map1); boost::fill_membership_map<Graph>(m_graph2, correspondence_map_2_to_1, membership_map2); // Generate filtered graphs using membership maps typedef typename boost::membership_filtered_graph_traits<Graph, MembershipMap>::graph_type MembershipFilteredGraph; MembershipFilteredGraph subgraph1 = boost::make_membership_filtered_graph(m_graph1, membership_map1); MembershipFilteredGraph subgraph2 = boost::make_membership_filtered_graph(m_graph2, membership_map2); VertexIndexMap vindex_map1 = get(boost::vertex_index, subgraph1); VertexIndexMap vindex_map2 = get(boost::vertex_index, subgraph2); VertexNameMap vname_map_common = get(boost::vertex_name, m_common_subgraph); VertexNameMap vname_map1 = get(boost::vertex_name, subgraph1); VertexNameMap vname_map2 = get(boost::vertex_name, subgraph2); EdgeNameMap ename_map_common = get(boost::edge_name, m_common_subgraph); EdgeNameMap ename_map1 = get(boost::edge_name, subgraph1); EdgeNameMap ename_map2 = get(boost::edge_name, subgraph2); // Verify that subgraph1 matches the supplied common subgraph BGL_FORALL_VERTICES_T(vertex1, subgraph1, MembershipFilteredGraph) { Vertex vertex_common = vertex(get(vindex_map1, vertex1), m_common_subgraph); // Match vertex names if (get(vname_map_common, vertex_common) != get(vname_map1, vertex1)) { // Keep looking return (true); } BGL_FORALL_VERTICES_T(vertex1_2, subgraph1, MembershipFilteredGraph) { Vertex vertex_common2 = vertex(get(vindex_map1, vertex1_2), m_common_subgraph); EdgeInfo edge_common = edge(vertex_common, vertex_common2, m_common_subgraph); EdgeInfo edge1 = edge(vertex1, vertex1_2, subgraph1); if ((edge_common.second != edge1.second) || ((edge_common.second && edge1.second) && (get(ename_map_common, edge_common.first) != get(ename_map1, edge1.first)))) { // Keep looking return (true); } }
typename graph_traits<Graph>::vertex_descriptor sloan_start_end_vertices(Graph& G, typename graph_traits<Graph>::vertex_descriptor &s, ColorMap color, DegreeMap degree) { typedef typename property_traits<DegreeMap>::value_type Degree; typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename std::vector< typename graph_traits<Graph>::vertices_size_type>::iterator vec_iter; typedef typename graph_traits<Graph>::vertices_size_type size_type; typedef typename property_map<Graph, vertex_index_t>::const_type VertexID; s = *(vertices(G).first); Vertex e = s; Vertex i; unsigned my_degree = get(degree, s ); unsigned dummy, h_i, h_s, w_i, w_e; bool new_start = true; unsigned maximum_degree = 0; //Creating a std-vector for storing the distance from the start vertex in dist std::vector<typename graph_traits<Graph>::vertices_size_type> dist(num_vertices(G), 0); //Wrap a property_map_iterator around the std::iterator boost::iterator_property_map<vec_iter, VertexID, size_type, size_type&> dist_pmap(dist.begin(), get(vertex_index, G)); //Creating a property_map for the indices of a vertex typename property_map<Graph, vertex_index_t>::type index_map = get(vertex_index, G); //Creating a priority queue typedef indirect_cmp<DegreeMap, std::greater<Degree> > Compare; Compare comp(degree); std::priority_queue<Vertex, std::vector<Vertex>, Compare> degree_queue(comp); //step 1 //Scan for the vertex with the smallest degree and the maximum degree typename graph_traits<Graph>::vertex_iterator ui, ui_end; for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) { dummy = get(degree, *ui); if(dummy < my_degree) { my_degree = dummy; s = *ui; } if(dummy > maximum_degree) { maximum_degree = dummy; } } //end 1 do{ new_start = false; //Setting the loop repetition status to false //step 2 //initialize the the disance std-vector with 0 for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0; //generating the RLS (rooted level structure) breadth_first_search (G, s, visitor ( make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) ) ); //end 2 //step 3 //calculating the depth of the RLS h_s = RLS_depth(dist); //step 4 //pushing one node of each degree in an ascending manner into degree_queue std::vector<bool> shrink_trace(maximum_degree, false); for (boost::tie(ui, ui_end) = vertices(G); ui != ui_end; ++ui) { dummy = get(degree, *ui); if( (dist[index_map[*ui]] == h_s ) && ( !shrink_trace[ dummy ] ) ) { degree_queue.push(*ui); shrink_trace[ dummy ] = true; } } //end 3 & 4 // step 5 // Initializing w w_e = (std::numeric_limits<unsigned>::max)(); //end 5 //step 6 //Testing for termination while( !degree_queue.empty() ) { i = degree_queue.top(); //getting the node with the lowest degree from the degree queue degree_queue.pop(); //ereasing the node with the lowest degree from the degree queue //generating a RLS for(typename std::vector<typename graph_traits<Graph>::vertices_size_type>::iterator iter = dist.begin(); iter != dist.end(); ++iter) *iter = 0; breadth_first_search (G, i, boost::visitor ( make_bfs_visitor(record_distances(dist_pmap, on_tree_edge() ) ) ) ); //Calculating depth and width of the rooted level h_i = RLS_depth(dist); w_i = RLS_max_width(dist, h_i); //Testing for termination if( (h_i > h_s) && (w_i < w_e) ) { h_s = h_i; s = i; while(!degree_queue.empty()) degree_queue.pop(); new_start = true; } else if(w_i < w_e) { w_e = w_i; e = i; } } //end 6 }while(new_start); return e; }
void CPlanarGraph::DetectFaces() { // Based on the example in (http://www.boost.org/doc/libs/1_47_0/libs/graph/example/planar_face_traversal.cpp) int numOfNodes = GetNumOfNodes(); Graph g(numOfNodes); int numOfEdges = GetNumOfEdges(); for ( int i=0; i<numOfEdges; i++ ) { int idx0 = GetEdge(i).GetIdx0(); int idx1 = GetEdge(i).GetIdx1(); add_edge(idx0, idx1, g); } // Initialize the interior edge index property_map<Graph, edge_index_t>::type e_index = get(edge_index, g); graph_traits<Graph>::edges_size_type edge_count = 0; graph_traits<Graph>::edge_iterator ei, ei_end; for ( boost::tuples::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei ) { put(e_index, *ei, edge_count++); } typedef std::vector< graph_traits<Graph>::edge_descriptor > vec_t; std::vector<vec_t> embedding(num_vertices(g)); #if 0 // Test for planarity - we know it is planar, we just want to // compute the planar embedding as a side-effect if ( boyer_myrvold_planarity_test(boyer_myrvold_params::graph = g, boyer_myrvold_params::embedding = &embedding[0] ) ) { std::cout << "Input graph is planar" << std::endl; } else { std::cout << "Input graph is not planar" << std::endl; } #else // Compute the planar embedding based on node positions... VertexIterator vi, vi_end; for ( boost::tie(vi, vi_end) = boost::vertices(g); vi != vi_end; ++vi ) { OutEdgeIterator ei, ei_end; std::vector<EdgeDescriptor> adjacentEdges; for ( boost::tie(ei, ei_end) = boost::out_edges(*vi, g); ei != ei_end; ++ei ) { VertexDescriptor v1 = boost::source(*ei, g); VertexDescriptor v2 = boost::target(*ei, g); adjacentEdges.push_back(*ei); } SortAdjacentVertices(g, *vi, adjacentEdges); for(int i = 0; i < adjacentEdges.size(); ++i) { std::cout << *vi << " -> " << adjacentEdges[i] << std::endl; } if(adjacentEdges.size()>0) std::cout << std::endl; embedding[*vi] = adjacentEdges; } #endif std::cout << std::endl << "Vertices on the faces: " << std::endl; vertex_output_visitor v_vis; planar_face_traversal(g, &embedding[0], v_vis); std::cout << std::endl << "Edges on the faces: " << std::endl; edge_output_visitor e_vis; planar_face_traversal(g, &embedding[0], e_vis); RemoveTheOutsideFace(); }
void LidarInpaintingHSVTextureVerification(TImage* const originalImage, Mask* const mask, const unsigned int patchHalfWidth, const unsigned int numberOfKNN, float slightBlurVariance = 1.0f, unsigned int searchRadius = 1000, float localRegionSizeMultiplier = 3.0f, float maxAllowedUsedPixelsRatio = 0.5f) { itk::ImageRegion<2> fullRegion = originalImage->GetLargestPossibleRegion(); // Extract the RGB image typedef itk::Image<itk::CovariantVector<float, 3>, 2> RGBImageType; std::vector<unsigned int> firstThreeChannels = {0,1,2}; RGBImageType::Pointer rgbImage = RGBImageType::New(); ITKHelpers::ExtractChannels(originalImage, firstThreeChannels, rgbImage.GetPointer()); // Create the HSV image typedef itk::Image<itk::CovariantVector<float, 3>, 2> HSVImageType; HSVImageType::Pointer hsvImage = HSVImageType::New(); ITKVTKHelpers::ConvertRGBtoHSV(rgbImage.GetPointer(), hsvImage.GetPointer()); ITKHelpers::WriteImage(hsvImage.GetPointer(), "HSVImage.mha"); // Stack the HSV image with the original rest of the channels typedef itk::Image<itk::CovariantVector<float, 5>, 2> HSVDxDyImageType; HSVDxDyImageType::Pointer hsvDxDyImage = HSVDxDyImageType::New(); ITKHelpers::DeepCopy(originalImage, hsvDxDyImage.GetPointer()); ITKHelpers::ReplaceChannels(hsvDxDyImage.GetPointer(), firstThreeChannels, hsvImage.GetPointer()); // Blur the image for gradient computation stability (Criminisi's data term) RGBImageType::Pointer blurredRGBImage = RGBImageType::New(); float blurVariance = 2.0f; MaskOperations::MaskedBlur(rgbImage.GetPointer(), mask, blurVariance, blurredRGBImage.GetPointer()); ITKHelpers::WriteRGBImage(blurredRGBImage.GetPointer(), "BlurredRGBImage.png"); // Blur the image slightly so that the SSD comparisons are not so noisy typename HSVDxDyImageType::Pointer slightlyBlurredHSVDxDyImage = TImage::New(); MaskOperations::MaskedBlur(hsvDxDyImage.GetPointer(), mask, slightBlurVariance, slightlyBlurredHSVDxDyImage.GetPointer()); ITKHelpers::WriteImage(slightlyBlurredHSVDxDyImage.GetPointer(), "SlightlyBlurredHSVDxDyImage.mha"); // Create the graph typedef ImagePatchPixelDescriptor<TImage> ImagePatchPixelDescriptorType; typedef boost::grid_graph<2> VertexListGraphType; // We can't make this a signed type (size_t versus int) because we allow negative boost::array<std::size_t, 2> graphSideLengths = { { fullRegion.GetSize()[0], fullRegion.GetSize()[1] } }; VertexListGraphType graph(graphSideLengths); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; typedef boost::graph_traits<VertexListGraphType>::vertex_iterator VertexIteratorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; IndexMapType indexMap(get(boost::vertex_index, graph)); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType; ImagePatchDescriptorMapType imagePatchDescriptorMap(num_vertices(graph), indexMap); // Create the patch inpainter. typedef PatchInpainter<TImage> OriginalImageInpainterType; OriginalImageInpainterType originalImagePatchInpainter(patchHalfWidth, originalImage, mask); originalImagePatchInpainter.SetDebugImages(true); originalImagePatchInpainter.SetImageName("RGB"); // Create an inpainter for the HSV image. typedef PatchInpainter<HSVImageType> HSVImageInpainterType; HSVImageInpainterType hsvImagePatchInpainter(patchHalfWidth, hsvImage, mask); // Create an inpainter for the RGB image. typedef PatchInpainter<RGBImageType> RGBImageInpainterType; RGBImageInpainterType rgbImagePatchInpainter(patchHalfWidth, rgbImage, mask); // Create an inpainter for the blurred image. typedef PatchInpainter<RGBImageType> BlurredImageInpainterType; BlurredImageInpainterType blurredRGBImagePatchInpainter(patchHalfWidth, blurredRGBImage, mask); // Create an inpainter for the slightly blurred image. typedef PatchInpainter<TImage> SlightlyBlurredHSVDxDyImageImageInpainterType; SlightlyBlurredHSVDxDyImageImageInpainterType slightlyBlurredHSVDxDyImageImagePatchInpainter(patchHalfWidth, slightlyBlurredHSVDxDyImage, mask); // Create a composite inpainter. (Note: the mask is inpainted in InpaintingVisitor::FinishVertex) CompositePatchInpainter inpainter; inpainter.AddInpainter(&originalImagePatchInpainter); inpainter.AddInpainter(&hsvImagePatchInpainter); inpainter.AddInpainter(&blurredRGBImagePatchInpainter); inpainter.AddInpainter(&slightlyBlurredHSVDxDyImageImagePatchInpainter); inpainter.AddInpainter(&rgbImagePatchInpainter); // Create the priority function typedef PriorityCriminisi<RGBImageType> PriorityType; PriorityType priorityFunction(blurredRGBImage, mask, patchHalfWidth); // priorityFunction.SetDebugLevel(1); // Queue typedef IndirectPriorityQueue<VertexListGraphType> BoundaryNodeQueueType; BoundaryNodeQueueType boundaryNodeQueue(graph); // Create the descriptor visitor (used for SSD comparisons). typedef ImagePatchDescriptorVisitor<VertexListGraphType, TImage, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; // ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(originalImage, mask, // imagePatchDescriptorMap, patchHalfWidth); // Use the non-blurred image for the SSD comparisons ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(slightlyBlurredHSVDxDyImage, mask, imagePatchDescriptorMap, patchHalfWidth); // Use the slightly blurred HSV image for the SSD comparisons. Make sure to use a *HSVSSD difference functor so the H differences are treated appropriately! typedef DefaultAcceptanceVisitor<VertexListGraphType> AcceptanceVisitorType; AcceptanceVisitorType acceptanceVisitor; // Create the inpainting visitor. (The mask is inpainted in FinishVertex) typedef InpaintingVisitor<VertexListGraphType, BoundaryNodeQueueType, ImagePatchDescriptorVisitorType, AcceptanceVisitorType, PriorityType, TImage> InpaintingVisitorType; InpaintingVisitorType inpaintingVisitor(mask, boundaryNodeQueue, imagePatchDescriptorVisitor, acceptanceVisitor, &priorityFunction, patchHalfWidth, "InpaintingVisitor", originalImage); inpaintingVisitor.SetDebugImages(true); // This produces PatchesCopied* images showing where patches were copied from/to at each iteration // inpaintingVisitor.SetAllowNewPatches(false); inpaintingVisitor.SetAllowNewPatches(true); // we can do this as long as we use one of the LinearSearchKNNProperty*Reuse (like LinearSearchKNNPropertyLimitLocalReuse) in the steps below InitializePriority(mask, boundaryNodeQueue, &priorityFunction); // Initialize the boundary node queue from the user provided mask image. InitializeFromMaskImage<InpaintingVisitorType, VertexDescriptorType>(mask, &inpaintingVisitor); std::cout << "PatchBasedInpaintingNonInteractive: There are " << boundaryNodeQueue.CountValidNodes() << " nodes in the boundaryNodeQueue" << std::endl; #define DUseWeightedDifference #ifdef DUseWeightedDifference // The absolute value of the depth derivative range is usually about [0,12], so to make // it comparable to to the color image channel range of [0,255], we multiply by 255/12 ~= 20. // float depthDerivativeWeight = 20.0f; // This should not be computed "by eye" by looking at the Dx and Dy channels of the PTX scan, because there are typically // huge depth discontinuties around the objects that are going to be inpainted. We'd have to look at the masked version of this // image to determine the min/max values of the unmasked pixels. They will be much smaller than the min/max values of the original // image, which will make the depth derivative weights much higher (~100 or so) // std::vector<typename TImage::PixelType> channelMins = ITKHelpers::ComputeMinOfAllChannels(originalImage); // std::vector<typename TImage::PixelType> channelMaxs = ITKHelpers::ComputeMaxOfAllChannels(originalImage); typename TImage::PixelType channelMins; ITKHelpers::ComputeMinOfAllChannels(originalImage, channelMins); typename TImage::PixelType channelMaxs; ITKHelpers::ComputeMaxOfAllChannels(originalImage, channelMaxs); float minX = fabs(channelMins[3]); float maxX = fabs(channelMaxs[3]); float maxValueX = std::max(minX, maxX); std::cout << "maxValueX = " << maxValueX << std::endl; float depthDerivativeWeightX = 255.0f / maxValueX; std::cout << "Computed depthDerivativeWeightX = " << depthDerivativeWeightX << std::endl; float minY = fabs(channelMins[4]); float maxY = fabs(channelMaxs[4]); float maxValueY = std::max(minY, maxY); std::cout << "maxValueY = " << maxValueY << std::endl; float depthDerivativeWeightY = 255.0f / maxValueY; std::cout << "Computed depthDerivativeWeightY = " << depthDerivativeWeightY << std::endl; // Use all channels std::vector<float> weights = {1.0f, 1.0f, 1.0f, depthDerivativeWeightX, depthDerivativeWeightY}; // typedef WeightedSumSquaredPixelDifference<typename TImage::PixelType> PixelDifferenceType; typedef WeightedHSVSSDFull<typename TImage::PixelType> FullPixelDifferenceType; FullPixelDifferenceType fullPixelDifferenceFunctor(weights); typedef ImagePatchDifference<ImagePatchPixelDescriptorType, FullPixelDifferenceType > FullPatchDifferenceType; FullPatchDifferenceType fullPatchDifferenceFunctor(fullPixelDifferenceFunctor); // Use only the first 3 channels typedef HSVSSD<typename TImage::PixelType> First3PixelDifferenceType; First3PixelDifferenceType first3PixelDifferenceFunctor; typedef ImagePatchDifference<ImagePatchPixelDescriptorType, First3PixelDifferenceType > First3PatchDifferenceType; First3PatchDifferenceType first3PatchDifferenceFunctor(first3PixelDifferenceFunctor); #else // Use an unweighted pixel difference typedef ImagePatchDifference<ImagePatchPixelDescriptorType, SumSquaredPixelDifference<typename TImage::PixelType> > PatchDifferenceType; PatchDifferenceType patchDifferenceFunctor; #endif //#define DAllowReuse // comment/uncomment this line to toggle allowing patches to be used as the source patch more than once #ifdef DAllowReuse // Create the first (KNN) neighbor finder typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, PatchDifferenceType> KNNSearchType; KNNSearchType linearSearchKNN(imagePatchDescriptorMap, numberOfKNN, patchDifferenceFunctor); #else typedef LinearSearchKNNPropertyLimitLocalReuse<ImagePatchDescriptorMapType, FullPatchDifferenceType, RGBImageType> KNNSearchType; KNNSearchType linearSearchKNN(imagePatchDescriptorMap, mask, numberOfKNN, localRegionSizeMultiplier, maxAllowedUsedPixelsRatio, fullPatchDifferenceFunctor, inpaintingVisitor.GetSourcePixelMapImage(), rgbImage.GetPointer()); linearSearchKNN.SetDebugImages(true); linearSearchKNN.SetDebugScreenOutputs(true); #endif //#else // This works the best, but is less useful for demonstrations // typedef LinearSearchKNNPropertyLimitLocalReuse<ImagePatchDescriptorMapType, FullPatchDifferenceType, RGBImageType> FullPixelKNNSearchType; // FullPixelKNNSearchType fullPixelSearchKNN(imagePatchDescriptorMap, mask, numberOfKNN, localRegionSizeMultiplier, maxAllowedUsedPixelsRatio, // fullPatchDifferenceFunctor, inpaintingVisitor.GetSourcePixelMapImage(), // rgbImage.GetPointer()); // fullPixelSearchKNN.SetDebugImages(true); // fullPixelSearchKNN.SetDebugScreenOutputs(true); // typedef LinearSearchKNNPropertyLimitLocalReuse<ImagePatchDescriptorMapType, First3PatchDifferenceType, RGBImageType> First3PixelKNNSearchType; // First3PixelKNNSearchType first3SearchKNN(imagePatchDescriptorMap, mask, numberOfKNN, localRegionSizeMultiplier, maxAllowedUsedPixelsRatio, // first3PatchDifferenceFunctor, inpaintingVisitor.GetSourcePixelMapImage(), // rgbImage.GetPointer()); // first3SearchKNN.SetDebugScreenOutputs(true); //// typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, First3PatchDifferenceType> First3PixelKNNSearchType; //// First3PixelKNNSearchType first3SearchKNN(imagePatchDescriptorMap, numberOfKNN, //// first3PatchDifferenceFunctor); //// first3SearchKNN.SetDebugImages(true); // typedef LinearSearchKNNPropertyCombine<FullPixelKNNSearchType, First3PixelKNNSearchType> KNNSearchType; // KNNSearchType linearSearchKNN(fullPixelSearchKNN, first3SearchKNN); //#endif // Setup the second (1-NN) neighbor finder typedef std::vector<VertexDescriptorType>::iterator VertexDescriptorVectorIteratorType; // This is templated on TImage because we need it to write out debug patches from this searcher (since we are not using an RGB image to compute the histograms) // typedef LinearSearchBestTexture<ImagePatchDescriptorMapType, HSVImageType, // VertexDescriptorVectorIteratorType, TImage> BestSearchType; // Use the histogram of the gradient magnitudes of a scalar represetnation of the image (e.g. magnitude image) // typedef LinearSearchBestLidarTextureDerivatives<ImagePatchDescriptorMapType, HSVImageType, // VertexDescriptorVectorIteratorType, TImage> BestSearchType; // Use the concatenated histograms of the absolute value of the derivatives of each channel // typedef LinearSearchBestLidarHSVTextureGradient<ImagePatchDescriptorMapType, HSVDxDyImageType, // VertexDescriptorVectorIteratorType, RGBImageType> BestSearchType; // Use the concatenated histograms of the gradient magnitudes of each channel. This HSVDxDyImageType must match the hsvDxDyImage provided below typedef LinearSearchBestLidarHSVTextureGradientWithSort<ImagePatchDescriptorMapType, HSVDxDyImageType, VertexDescriptorVectorIteratorType, RGBImageType> BestSearchType; // Use the concatenated histograms of the gradient magnitudes of each channel. This HSVDxDyImageType must match the hsvDxDyImage provided below. Also sort the patches for demonstrative output purposes. // BestSearchType linearSearchBest(imagePatchDescriptorMap, hsvDxDyImage.GetPointer(), mask); // use non-blurred for texture sorting Debug bestSearchTypeDebug; bestSearchTypeDebug.SetDebugScreenOutputs(true); // bestSearchTypeDebug.SetDebugImages(true); // linearSearchBest.SetDebugOutputs(true); // linearSearchBest.SetDebugImages(true); // use slightly blurred for texture sorting BestSearchType linearSearchBest(imagePatchDescriptorMap, slightlyBlurredHSVDxDyImage.GetPointer(), mask, rgbImage.GetPointer(), bestSearchTypeDebug); // linearSearchBest.SetDebugImages(false); linearSearchBest.SetDebugImages(true); // This produces BestPatch* images showing the list of the top K patches that were passed to the BestSearch functor // Setup the two step neighbor finder TwoStepNearestNeighbor<KNNSearchType, BestSearchType> twoStepNearestNeighbor(linearSearchKNN, linearSearchBest); // #define DFullSearch // comment/uncomment this line to set the search region #ifdef DFullSearch // Perform the inpainting (full search) InpaintingAlgorithm(graph, inpaintingVisitor, &boundaryNodeQueue, twoStepNearestNeighbor, &inpainter); #else NeighborhoodSearch<VertexDescriptorType, ImagePatchDescriptorMapType> neighborhoodSearch(originalImage->GetLargestPossibleRegion(), searchRadius, imagePatchDescriptorMap); // Perform the inpainting (local search) bool algorithmDebug = true; InpaintingAlgorithmWithLocalSearch(graph, inpaintingVisitor, &boundaryNodeQueue, twoStepNearestNeighbor, &inpainter, neighborhoodSearch, algorithmDebug); #endif }
template <typename PointT> void pcl::registration::ELCH<PointT>::loopOptimizerAlgorithm (LOAGraph &g, double *weights) { std::list<int> crossings, branches; crossings.push_back (static_cast<int> (loop_start_)); crossings.push_back (static_cast<int> (loop_end_)); weights[loop_start_] = 0; weights[loop_end_] = 1; int *p = new int[num_vertices (g)]; int *p_min = new int[num_vertices (g)]; double *d = new double[num_vertices (g)]; double *d_min = new double[num_vertices (g)]; double dist; bool do_swap = false; std::list<int>::iterator crossings_it, end_it, start_min, end_min; // process all junctions while (!crossings.empty ()) { dist = -1; // find shortest crossing for all vertices on the loop for (crossings_it = crossings.begin (); crossings_it != crossings.end (); ) { dijkstra_shortest_paths (g, *crossings_it, predecessor_map(boost::make_iterator_property_map(p, get(boost::vertex_index, g))). distance_map(boost::make_iterator_property_map(d, get(boost::vertex_index, g)))); end_it = crossings_it; end_it++; // find shortest crossing for one vertex for (; end_it != crossings.end (); end_it++) { if (*end_it != p[*end_it] && (dist < 0 || d[*end_it] < dist)) { dist = d[*end_it]; start_min = crossings_it; end_min = end_it; do_swap = true; } } if (do_swap) { std::swap (p, p_min); std::swap (d, d_min); do_swap = false; } // vertex starts a branch if (dist < 0) { branches.push_back (static_cast<int> (*crossings_it)); crossings_it = crossings.erase (crossings_it); } else crossings_it++; } if (dist > -1) { remove_edge (*end_min, p_min[*end_min], g); for (int i = p_min[*end_min]; i != *start_min; i = p_min[i]) { //even right with weights[*start_min] > weights[*end_min]! (math works) weights[i] = weights[*start_min] + (weights[*end_min] - weights[*start_min]) * d_min[i] / d_min[*end_min]; remove_edge (i, p_min[i], g); if (degree (i, g) > 0) { crossings.push_back (i); } } if (degree (*start_min, g) == 0) crossings.erase (start_min); if (degree (*end_min, g) == 0) crossings.erase (end_min); } } delete[] p; delete[] p_min; delete[] d; delete[] d_min; boost::graph_traits<LOAGraph>::adjacency_iterator adjacent_it, adjacent_it_end; int s; // error propagation while (!branches.empty ()) { s = branches.front (); branches.pop_front (); for (boost::tuples::tie (adjacent_it, adjacent_it_end) = adjacent_vertices (s, g); adjacent_it != adjacent_it_end; ++adjacent_it) { weights[*adjacent_it] = weights[s]; if (degree (*adjacent_it, g) > 1) branches.push_back (static_cast<int> (*adjacent_it)); } clear_vertex (s, g); } }
void mig_cuts_paged::enumerate_partial( const std::vector<mig_node>& start, const std::vector<mig_node>& boundary ) { reference_timer t( &_enumeration_time ); std::vector<mig_node> colors( num_vertices( _mig ), 0u ); /* children */ data.assign_empty( 0u, {0u, 0u} ); cones.assign_empty( 0u ); colors[0u] = 2u; for ( auto n : boundary ) { if ( n == 0 ) { continue; } data.assign_singleton( n, n, {0u, 1u} ); cones.assign_singleton( n, n ); colors[n] = 2u; } /* create order */ std::vector<mig_node> topo; std::stack<mig_node> stack; for ( auto root : start ) { stack.push( root ); } while ( !stack.empty() ) { auto n = stack.top(); switch ( colors[n] ) { case 0u: { auto it = adjacent_vertices( n, _mig ).first; const auto n1 = *it++; const auto n2 = *it++; const auto n3 = *it++; colors[n] = 1u; stack.push( n3 ); stack.push( n2 ); stack.push( n1 ); } break; case 1u: colors[n] = 2u; topo.push_back( n ); stack.pop(); break; case 2u: stack.pop(); break; } } //std::cout << "[i] start: " << any_join( start, ", " ) << ", boundary: " << any_join( boundary, ", " ) << ", topo: " << any_join( topo, ", " ) << std::endl; for ( auto n : topo ) { data.append_begin( n ); cones.append_begin( n ); /* get children */ auto it = adjacent_vertices( n, _mig ).first; const auto n1 = *it++; const auto n2 = *it++; const auto n3 = *it++; _top_index = num_vertices( _mig ); enumerate_node_with_bitsets( n, n1, n2, n3 ); data.append_singleton( n, n, {0u, 1u} ); cones.append_singleton( n, n ); } }
int main(int argc, const char * argv[]) { // insert code here... //comment after testing: std::ifstream in(getenv("INPUT")); std::cin.rdbuf(in.rdbuf()); // const unsigned numOfEdges = 3826930; const unsigned numOfEdges = 3753288; /* Build graph with sources, targets and dists */ graph_t AMinerGraph(1712431); for (unsigned edgeIndex = 0; edgeIndex<numOfEdges; ++edgeIndex) boost::add_edge(sources[edgeIndex],targets[edgeIndex],1-dists[edgeIndex],AMinerGraph); std::vector<vertex_descriptor> p(num_vertices(AMinerGraph)); std::vector<double> d(num_vertices(AMinerGraph)); /* Create mongodb client */ std::string uri = "mongodb://localhost:27017"; std::string errmsg; mongo::ConnectionString cs = mongo::ConnectionString::parse(uri, errmsg); if (!cs.isValid()) { return EXIT_FAILURE; } boost::scoped_ptr<mongo::DBClientBase> conn(cs.connect(errmsg)); if ( !conn ) { return EXIT_FAILURE; } /* Get skills from stdin */ std::string inputLine; std::vector<std::string> columns; std::vector<skill> skills; while (getline(std::cin,inputLine)) { /* clear vectors: p, d, skills, columns */ p.clear(); d.clear(); skills.clear(); columns.clear(); csvRead::csvline_populate(columns, inputLine, '\t'); int taskIndex = atoi(columns[0].c_str()); int numOfSkills = (taskIndex/100+1)*4; for (int skillIndex = 1; skillIndex<=numOfSkills; ++skillIndex) { std::string skillName = columns[skillIndex]; mongo::BSONObj skillSearchObj = BSON("Skill"<<skillName); std::auto_ptr<mongo::DBClientCursor> cursor = conn->query(/*"AMinerDB*/"GuruDB.skillCollection", skillSearchObj,0,0,NULL,mongo::QueryOption_NoCursorTimeout); if (!cursor.get()) { return EXIT_FAILURE; } mongo::BSONObj skillNode = cursor->next(); unsigned expertSize = skillNode.getIntField("ExpertSize"); std::vector<mongo::BSONElement> experts = skillNode["ExpertIndex"].Array(); skill tmpSkill(skillName,expertSize); for(auto expert:experts) { tmpSkill.push_back(expert.numberLong()); } skills.push_back(tmpSkill); } std::time_t realStart = clock(); std::string rarestSkill = columns[numOfSkills+1]; int candidateIndex = std::atoi(columns[columns.size()-1].c_str()); // 计算基于 candidateIndex 的最短距离 vertex_descriptor s = vertex(candidateIndex,AMinerGraph); dijkstra_shortest_paths_no_color_map(AMinerGraph, s, boost::predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, AMinerGraph))). distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, AMinerGraph)))); /* Begin MinSD Algorithm */ double sumOfDist = 0; std::time_t start = clock(); for (auto &reqSKill : skills) { double distance = 999999; for (auto expert : reqSKill.holders) { if(d[expert]<distance) { distance = d[expert]; reqSKill.i_prem = expert; } } sumOfDist += distance; } // Algorithm finished std::time_t end = clock() - start; std::time_t realEnd = end + start - realStart; std::cout << taskIndex << '\t' << sumOfDist << '\t' << end*1000.0/CLOCKS_PER_SEC<<'\t'<<realEnd*1000.0/CLOCKS_PER_SEC<<'\t'<< candidateIndex; if (sumOfDist > 999999) { std::cout << std::endl; continue; } std::set<unsigned long> experts; experts.insert(candidateIndex); for (auto reqSkill : skills) { unsigned long des = p[reqSkill.i_prem]; do { experts.insert(des); des = p[des]; }while (des != candidateIndex); } //revision: for (auto reqSkill : skills) { experts.insert(reqSkill.i_prem); } for (auto expert :experts) { std::cout<< '\t' << expert; } std::cout << std::endl; } std::cout << "Hello, World!\n"; return 0; }
void dijkstra_shortest_paths_no_color_map_no_init (const Graph& graph, typename graph_traits<Graph>::vertex_descriptor start_vertex, PredecessorMap predecessor_map, DistanceMap distance_map, WeightMap weight_map, VertexIndexMap index_map, DistanceCompare distance_compare, DistanceWeightCombine distance_weight_combine, DistanceInfinity distance_infinity, DistanceZero distance_zero, DijkstraVisitor visitor) { typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename property_traits<DistanceMap>::value_type Distance; typedef indirect_cmp<DistanceMap, DistanceCompare> DistanceIndirectCompare; DistanceIndirectCompare distance_indirect_compare(distance_map, distance_compare); // Choose vertex queue type #if BOOST_GRAPH_DIJKSTRA_USE_RELAXED_HEAP typedef relaxed_heap<Vertex, DistanceIndirectCompare, VertexIndexMap> VertexQueue; VertexQueue vertex_queue(num_vertices(graph), distance_indirect_compare, index_map); #else // Default - use d-ary heap (d = 4) typedef detail::vertex_property_map_generator<Graph, VertexIndexMap, std::size_t> IndexInHeapMapHelper; typedef typename IndexInHeapMapHelper::type IndexInHeapMap; typedef d_ary_heap_indirect<Vertex, 4, IndexInHeapMap, DistanceMap, DistanceCompare> VertexQueue; boost::scoped_array<std::size_t> index_in_heap_map_holder; IndexInHeapMap index_in_heap = IndexInHeapMapHelper::build(graph, index_map, index_in_heap_map_holder); VertexQueue vertex_queue(distance_map, index_in_heap, distance_compare); #endif // Add vertex to the queue vertex_queue.push(start_vertex); // Starting vertex will always be the first discovered vertex visitor.discover_vertex(start_vertex, graph); while (!vertex_queue.empty()) { Vertex min_vertex = vertex_queue.top(); vertex_queue.pop(); visitor.examine_vertex(min_vertex, graph); // Check if any other vertices can be reached Distance min_vertex_distance = get(distance_map, min_vertex); if (!distance_compare(min_vertex_distance, distance_infinity)) { // This is the minimum vertex, so all other vertices are unreachable return; } // Examine neighbors of min_vertex BGL_FORALL_OUTEDGES_T(min_vertex, current_edge, graph, Graph) { visitor.examine_edge(current_edge, graph); // Check if the edge has a negative weight if (distance_compare(get(weight_map, current_edge), distance_zero)) { boost::throw_exception(negative_edge()); } // Extract the neighboring vertex and get its distance Vertex neighbor_vertex = target(current_edge, graph); Distance neighbor_vertex_distance = get(distance_map, neighbor_vertex); bool is_neighbor_undiscovered = !distance_compare(neighbor_vertex_distance, distance_infinity); // Attempt to relax the edge bool was_edge_relaxed = relax(current_edge, graph, weight_map, predecessor_map, distance_map, distance_weight_combine, distance_compare); if (was_edge_relaxed) { visitor.edge_relaxed(current_edge, graph); if (is_neighbor_undiscovered) { visitor.discover_vertex(neighbor_vertex, graph); vertex_queue.push(neighbor_vertex); } else { vertex_queue.update(neighbor_vertex); } } else { visitor.edge_not_relaxed(current_edge, graph); } } // end out edge iteration visitor.finish_vertex(min_vertex, graph); } // end while queue not empty
typename property_traits<CoreMap>::value_type core_numbers_impl(Graph& g, CoreMap c, PositionMap pos, Visitor vis) { typedef typename graph_traits<Graph>::vertices_size_type size_type; typedef typename graph_traits<Graph>::degree_size_type degree_type; typedef typename graph_traits<Graph>::vertex_descriptor vertex; typename graph_traits<Graph>::vertex_iterator vi,vi_end; // store the vertex core numbers typename property_traits<CoreMap>::value_type v_cn = 0; // compute the maximum degree (degrees are in the coremap) typename graph_traits<Graph>::degree_size_type max_deg = 0; for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { max_deg = (std::max<typename graph_traits<Graph>::degree_size_type>)(max_deg, get(c,*vi)); } // store the vertices in bins by their degree // allocate two extra locations to ease boundary cases std::vector<size_type> bin(max_deg+2); for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { ++bin[get(c,*vi)]; } // this loop sets bin[d] to the starting position of vertices // with degree d in the vert array for the bucket sort size_type cur_pos = 0; for (degree_type cur_deg = 0; cur_deg < max_deg+2; ++cur_deg) { degree_type tmp = bin[cur_deg]; bin[cur_deg] = cur_pos; cur_pos += tmp; } // perform the bucket sort with pos and vert so that // pos[0] is the vertex of smallest degree std::vector<vertex> vert(num_vertices(g)); for (boost::tie(vi,vi_end) = vertices(g); vi!=vi_end; ++vi) { vertex v=*vi; size_type p=bin[get(c,v)]; put(pos,v,p); vert[p]=v; ++bin[get(c,v)]; } // we ``abused'' bin while placing the vertices, now, // we need to restore it std::copy(boost::make_reverse_iterator(bin.end()-2), boost::make_reverse_iterator(bin.begin()), boost::make_reverse_iterator(bin.end()-1)); // now simulate removing the vertices for (size_type i=0; i < num_vertices(g); ++i) { vertex v = vert[i]; vis.examine_vertex(v,g); v_cn = get(c,v); typename graph_traits<Graph>::out_edge_iterator oi,oi_end; for (boost::tie(oi,oi_end) = out_edges(v,g); oi!=oi_end; ++oi) { vis.examine_edge(*oi,g); vertex u = target(*oi,g); // if c[u] > c[v], then u is still in the graph, if (get(c,u) > v_cn) { degree_type deg_u = get(c,u); degree_type pos_u = get(pos,u); // w is the first vertex with the same degree as u // (this is the resort operation!) degree_type pos_w = bin[deg_u]; vertex w = vert[pos_w]; if (u!=v) { // swap u and w put(pos,u,pos_w); put(pos,w,pos_u); vert[pos_w] = u; vert[pos_u] = w; } // now, the vertices array is sorted assuming // we perform the following step // start the set of vertices with degree of u // one into the future (this now points at vertex // w which we swapped with u). ++bin[deg_u]; // we are removing v from the graph, so u's degree // decreases put(c,u,get(c,u)-1); } } vis.finish_vertex(v,g); } return v_cn; }
int main(int argc, const char * argv[]) { //comment after testing: std::ifstream in(getenv("INPUT")); std::cin.rdbuf(in.rdbuf()); // const unsigned numOfEdges = 3826930; const unsigned numOfEdges = 3753288; /* Build graph with sources, targets and dists */ graph_t AMinerGraph(NUM_OF_NODES); for (unsigned edgeIndex = 0; edgeIndex<numOfEdges; ++edgeIndex) boost::add_edge(sources[edgeIndex],targets[edgeIndex],1-dists[edgeIndex],AMinerGraph); std::vector<vertex_descriptor> p(num_vertices(AMinerGraph)); std::vector<double> d(num_vertices(AMinerGraph)); /* Create mongodb client */ std::string uri = "mongodb://localhost:27017"; std::string errmsg; mongo::ConnectionString cs = mongo::ConnectionString::parse(uri, errmsg); if (!cs.isValid()) { return EXIT_FAILURE; } boost::scoped_ptr<mongo::DBClientBase> conn(cs.connect(errmsg)); if ( !conn ) { return EXIT_FAILURE; } /* Get skills from stdin */ std::string inputLine; std::vector<std::string> columns; std::vector<skill> skills; std::srand(time(0)); while (getline(std::cin,inputLine)) { /* clear vectors: p, d, skills, columns */ p.clear(); d.clear(); skills.clear(); columns.clear(); std::time_t realStart = clock(); csvRead::csvline_populate(columns, inputLine, '\t'); int taskIndex = atoi(columns[0].c_str()); int numOfSkills = (taskIndex/100+1)*4; std::vector<Skill_Holder_Capa> skillHolders; for (int skillIndex = 1; skillIndex<=numOfSkills; ++skillIndex) { std::string skillName = columns[skillIndex]; mongo::BSONObj skillSearchObj = BSON("Skill"<<skillName); std::auto_ptr<mongo::DBClientCursor> cursor = conn->query("GuruDB.skillCollection"/*"AMinerDB.skillCollection"*/, skillSearchObj,0,0,NULL,mongo::QueryOption_NoCursorTimeout); if (!cursor.get()) { return EXIT_FAILURE; } mongo::BSONObj skillNode = cursor->next(); unsigned expertSize = skillNode.getIntField("ExpertSize"); std::vector<mongo::BSONElement> experts = skillNode["ExpertIndex"].Array(); skill tmpSkill(skillName,expertSize); for(auto expert:experts) { tmpSkill.push_back(expert.numberLong(),std::ceil(capacity[expert.numberLong()])); Skill_Holder_Capa shc; shc.name = expert.numberLong(); shc.capacity = std::ceil(capacity[shc.name]); shc.skillIndex = skillIndex; skillHolders.push_back(shc); } skills.push_back(tmpSkill); } std::string rarestSkill = columns[numOfSkills+1]; unsigned long candidateIndex = 0, count; do { count = 0; int randIndex = std::rand()%skillHolders.size(); candidateIndex = skillHolders[randIndex].name; vertex_descriptor s = vertex(candidateIndex,AMinerGraph); dijkstra_shortest_paths_no_color_map(AMinerGraph, s, boost::predecessor_map(boost::make_iterator_property_map(p.begin(), get(boost::vertex_index, AMinerGraph))). distance_map(boost::make_iterator_property_map(d.begin(), get(boost::vertex_index, AMinerGraph)))); for (auto &holder :skillHolders) { holder.distance = d[holder.name]; count += (d[holder.name]>9999)? 1:0; } }while (count>skillHolders.size()/2); /* Begin MDS Algorithm */ std::time_t start = clock(); std::sort(skillHolders.begin(), skillHolders.end(), greaterCost()); unsigned r_begin = 0, r_end = skillHolders.size() - count - 1; unsigned minDiaIndex = r_end + 1; std::set<unsigned long>solution; while (true) { MFGraph maxFlowGraph; boost::property_map<MFGraph, boost::edge_capacity_t>::type edgeCapacity = get(boost::edge_capacity, maxFlowGraph); boost::property_map<MFGraph, boost::edge_reverse_t>::type rev = get(boost::edge_reverse, maxFlowGraph); boost::property_map<MFGraph, boost::edge_residual_capacity_t>::type residual_capacity = get(boost::edge_residual_capacity, maxFlowGraph); Traits::vertex_descriptor source, end; unsigned r_mid = (r_begin+r_end)/2, length = r_mid + skills.size() +2; std::vector<MF_vertex_descriptor> verts; /* build up max flow graph */ for (unsigned long vi = 0; vi < length; ++vi) { verts.push_back(boost::add_vertex(maxFlowGraph)); } source = verts[0]; end = verts[length-1]; // add edge out from source and into target for (unsigned long index = 0; index < verts.size()-1; ++index) { MF_edge_descriptor e1, e2; bool in1, in2; long tail, head; long cap; if (index < skills.size()) { tail = 0; head = index + 1; cap = 1; } else { tail = index + 1; head = length -1; cap = skillHolders[index-skills.size()].capacity; long skillTail = skillHolders[index-skills.size()].skillIndex; long skillHead = tail; boost::tie(e1, in1) = boost::add_edge(verts[skillTail], verts[skillHead], maxFlowGraph); boost::tie(e2, in2) = boost::add_edge(verts[skillHead], verts[skillTail], maxFlowGraph); if (!in1 || !in2) { std::cerr << "unable to add edge (" << head << "," << tail << ")" << std::endl; return -1; } edgeCapacity[e1] = 1; edgeCapacity[e2] = 0; rev[e1] = e2; rev[e2] = e1; } boost::tie(e1, in1) = boost::add_edge(verts[tail], verts[head], maxFlowGraph); boost::tie(e2, in2) = boost::add_edge(verts[head], verts[tail], maxFlowGraph); if (!in1 || !in2) { std::cerr << "unable to add edge (" << head << "," << tail << ")" << std::endl; return -1; } edgeCapacity[e1] = cap; edgeCapacity[e2] = 0; rev[e1] = e2; rev[e2] = e1; } long flow; #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 // Use non-named parameter version boost::property_map<MFGraph, boost::vertex_index_t>::type indexmap = get(boost::vertex_index, maxFlowGraph); flow = push_relabel_max_flow(maxFlowGraph, source, end, edgeCapacity, residual_capacity, rev, indexmap); #else flow = push_relabel_max_flow(maxFlowGraph, source, end); #endif if (flow == skills.size()) { // solution.clear(); boost::graph_traits<MFGraph>::vertex_iterator u_iter, u_end; boost::graph_traits<MFGraph>::out_edge_iterator ei, e_end; for (boost::tie(u_iter, u_end) = vertices(maxFlowGraph); u_iter != u_end; ++u_iter) { if (*u_iter==0||*u_iter>skills.size()) { continue; } for (boost::tie(ei, e_end) = out_edges(*u_iter, maxFlowGraph); ei != e_end; ++ei) { if (edgeCapacity[*ei] > 0 && edgeCapacity[*ei] - residual_capacity[*ei] > 0) solution.insert(skillHolders[target(*ei, maxFlowGraph) -skills.size()-1].name); //std::cout << "f " << *u_iter << " " << target(*ei, g) << " " //<< (capacity[*ei] - residual_capacity[*ei]) << std::endl; } } r_end = r_mid; if (r_mid < minDiaIndex) { minDiaIndex = r_mid; } if (r_end<=r_begin) { break; } } else if (flow < skills.size()) { r_begin = r_mid + 1; if (r_begin >= r_end) { break; } } else { std::cout << "ERROR" << std::endl; break; } } // Algorithm finished std::time_t realEnd = clock(); std::cout << taskIndex << '\t' << skillHolders[minDiaIndex].distance << '\t' << (clock() - start)*1000.0/CLOCKS_PER_SEC<<"\t"<<(realEnd - realStart)*1000.0/CLOCKS_PER_SEC << '\t'<< candidateIndex; if (skillHolders[r_end].distance>9999) { std::cout<<std::endl; continue; } for (auto reqSkill:skills) { std::cout<<"\t"<<reqSkill.getName(); } if (solution.empty()) continue; std::set<unsigned long>experts; for (auto expert : solution) { experts.insert(expert); unsigned long des = p[expert]; do { experts.insert(des); des = p[des]; }while(des != candidateIndex); } for (auto expert : experts) { std::cout<<"\t"<<expert; } std::cout<<std::endl; } std::cout<< "Hello, World!\n"; return 0; }
vertex_descriptor goal() const { return vertex(num_vertices(m_grid)-1, m_grid); }
bool is_reachable(typename graph_traits<Graph>::vertex_descriptor u, typename graph_traits<Graph>::vertex_descriptor v, Graph const& g) { one_bit_color_map<> map(num_vertices(g)); return is_reachable(u, v, g, map); }
int main(int,char*[]) { Triangulation t; t.insert(Point(0.1,0,1)); t.insert(Point(1,0,1)); t.insert(Point(0.2,0.2, 2)); t.insert(Point(0,1,2)); t.insert(Point(0,2,3)); vertex_iterator vit, ve; // Associate indices to the vertices int index = 0; // boost::tie assigns the first and second element of the std::pair // returned by boost::vertices to the variables vit and ve for(boost::tie(vit,ve) = vertices(t); vit!=ve; ++vit ){ vertex_descriptor vd = *vit; if(! t.is_infinite(vd)){ vertex_id_map[vd]= index++; } } std::cerr << index << " vertices" << std::endl; index = 0; face_iterator fit,fe; for(boost::tie(fit,fe) = faces(t); fit!= fe; ++fit){ face_descriptor fd = *fit; halfedge_descriptor hd = halfedge(fd,t); halfedge_descriptor n = next(hd,t); halfedge_descriptor nn = next(n,t); if(next(nn,t) != hd){ std::cerr << "the face is not a triangle" << std::endl; } ++index; } std::cerr << index << " faces" << std::endl; index = 0; edge_iterator eit,ee; for(boost::tie(eit,ee) = edges(t); eit!= ee; ++eit){ edge_descriptor ed = *eit; vertex_descriptor vd = source(ed,t); CGAL_USE(vd); ++index; } std::cerr << index << " edges" << std::endl; index = 0; halfedge_iterator hit,he; for(boost::tie(hit,he) = halfedges(t); hit!= he; ++hit){ halfedge_descriptor hd = *hit; vertex_descriptor vd = source(hd,t); CGAL_USE(vd); ++index; } std::cerr << index << " halfedges" << std::endl; std::cerr << num_vertices(t) << " " << num_edges(t) << " " << num_halfedges(t) << " " << num_faces(t) << std::endl; typedef boost::property_map<Triangulation, boost::vertex_point_t>::type Ppmap; Ppmap ppmap = get(boost::vertex_point, t); for(vertex_descriptor vd : vertices_around_target(*vertices(t).first, t)){ std::cout << ppmap[vd] << std::endl; } ppmap[*(++vertices(t).first)] = Point(78,1,2); std::cout << " changed point of vertex " << ppmap[*(++vertices(t).first)] << std::endl; return 0; }
size_t num_local_vertices () { return num_vertices(); }
/** * Returns the data of the vertex in the i'th position in this shard. * vertex_data(i) corresponds to the data on the vertex with ID vertex(i) * i must range from 0 to num_vertices() - 1 inclusive. */ inline graph_row* vertex_data(size_t i) { ASSERT_LT(i, num_vertices()); return &(shard_impl.vertex_data[0])+i; }
void Garnet::convertIVGraphToPPEGraph(Garnet::IVGraph& iv, Garnet::PPEGraph& pg, const ConfigStore& conf, TraceStore& trace) { typedef PPEGraph::vertex_descriptor PVertex; typedef PPEGraph::edge_descriptor PEdge; StopWatch watch; // 1. Crack IV node into a set of PPE node. for (auto vpair = vertices(iv); vpair.first != vpair.second; vpair.first++) { auto u_iv = *vpair.first; PPEGraph::vertex_descriptor u, v, w; if ( Text::startsWith(iv[u_iv].label, "_IVStore") ) { // 1.1 Root node. // Add I, V and A nodes into PPE graph. uint32_t reg = strtoul(iv[u_iv].label.c_str() + strlen("_IVStore"), 0, 0); u = boost::add_vertex(pg); // I v = boost::add_vertex(pg); // V w = boost::add_vertex(pg); // A pg[u].label = "Move"; pg[v].label = "Move"; pg[w].label = "Move"; pg[u].type = _RI1B; pg[v].type = _RV1D; pg[w].type = _RA1D; pg[u].color = reg; pg[v].color = reg; pg[w].color = -1; // A node is intended to be an intron. } else if ( Text::startsWith(iv[u_iv].label, "_VAStore") ) { // 1.1 Root node. // Add I, V and A nodes into PPE graph. uint32_t reg = strtoul(iv[u_iv].label.c_str() + strlen("_VAStore"), 0, 0); u = boost::add_vertex(pg); v = boost::add_vertex(pg); w = boost::add_vertex(pg); pg[u].label = "Move"; pg[v].label = "Move"; pg[w].label = "Move"; pg[u].type = _RI1B; pg[v].type = _RV1D; pg[w].type = _RA1D; pg[u].color = -1; // I node is intendd to be an intron. pg[v].color = reg; pg[w].color = reg; } else if ( Text::startsWith(iv[u_iv].label, "_Src") ) { // 1.2 Source Terminal node. // Add I, V, and A nodes into PPE graph. uint32_t reg = strtoul(iv[u_iv].label.c_str() + strlen("_Src"), 0, 0); u = boost::add_vertex(pg); v = boost::add_vertex(pg); w = boost::add_vertex(pg); pg[u].label = "Move"; pg[v].label = "Move"; pg[w].label = "Move"; pg[u].type = _SI3B; pg[v].type = _SV1D; pg[w].type = _SA1D; pg[u].color = reg; pg[v].color = reg; pg[w].color = reg; } else if ( Text::startsWith(iv[u_iv].label, "_Load") ) { // 1.2 Source Terminal node. // Add I, V, and A nodes into PPE graph. uint32_t reg = strtoul(iv[u_iv].label.c_str() + strlen("_Load"), 0, 0); u = boost::add_vertex(pg); v = boost::add_vertex(pg); w = boost::add_vertex(pg); pg[u].label = "Move"; pg[v].label = "Move"; pg[w].label = "Move"; pg[u].type = _SI1B; pg[v].type = _SV1D; pg[w].type = _SA1D; pg[u].color = reg; pg[v].color = reg; pg[w].color = reg; } else { // 1.2.1 Find an entry with this vertex's name from the dictionary. const Garnet::IVInstruction& dict = Garnet::Dictionary::findByIVName(iv[u_iv].label); // 1.2.2 Intermediate node or non-source terminal node. // Add I, V, and A nodes into PPE graph. u = boost::add_vertex(pg); v = boost::add_vertex(pg); w = boost::add_vertex(pg); pg[u].label = dict.pp[0].label; pg[v].label = dict.pp[1].label; pg[w].label = dict.pp[2].label; pg[u].type = dict.pp[0].outputType; pg[v].type = dict.pp[1].outputType; pg[w].type = dict.pp[2].outputType; pg[u].color = -1; pg[v].color = -1; pg[w].color = -1; } //pg[u].tree = iv[u_iv].tree; //pg[v].tree = iv[u_iv].tree; //pg[w].tree = iv[u_iv].tree; } //std::cout << "\n" << __LINE__ << std::endl; // 2. Connect // PPEGraph and IVGraph use vector as vertex and edge list storage, // so these descriptors are integer values. // A IV filter with index x corresponds to PPE filters index x*3+0, x*3+1 and x*3+2. for (auto vpair = vertices(iv); vpair.first != vpair.second; vpair.first++) { auto u = *vpair.first; #define ADD_SINK_EDGE(ppType) {\ PPEGraph::vertex_descriptor v = MAKE_PP_INDEX(out_edges(u, iv).first->m_target, (ppType)); \ while ( Text::equals(pg[v].label, "Move") && out_degree(v, pg) > 0 ) { \ v = out_edges(v, pg).first->m_target;\ } \ add_edge(MAKE_PP_INDEX(u, (ppType)), v, pg);\ } // 2.2 Add edges. if ( Text::startsWith(iv[u].label, "_IVStore") ) { // 2.2.1 Add edges for Sink. // Sink is cracked two Move operations with preassigned // Result register number. // No A edge for 'Sink'. ADD_SINK_EDGE(0); // I ADD_SINK_EDGE(1); // V } else if ( Text::startsWith(iv[u].label, "_VAStore") ) { // 2.2.2 Add edges for VASink. // Sink is cracked two Move operations with preassigned // Result register number. // No I edge for VASink. ADD_SINK_EDGE(1); // V ADD_SINK_EDGE(2); // A } else if ( Text::startsWith(iv[u].label, "_Src") || Text::startsWith(iv[u].label, "_Load") ){ // Source vertices does not need connect any edges. continue; } else { // 2.2.5.1 Find an entry with this vertex's name from the dictionary. const Garnet::IVInstruction& dict = Garnet::Dictionary::findByIVName(iv[*vpair.first].label); // 2.2.5.2 Add edges for filters by following dictionary. for (auto t = 0; t < NUM_PP_PER_FILTER; t++) { // t=0 -> I, t=1 -> V, t=2 -> A. // Add edges for inputs. for (auto i = 0u; dict.pp[t].input[i] != _NULL; i++) { IVGraph::vertex_descriptor ipos = (out_edges(u, iv).first + dict.pp[t].input[i] / NUM_PP_PER_FILTER)->m_target; int type = dict.pp[t].input[i] % NUM_PP_PER_FILTER; // Skip "Move" nodes in PPE graph. // If terminal node is found, end search and connect to it. while ( Text::equals(pg[MAKE_PP_INDEX(ipos, type)].label, "Move") && pg[MAKE_PP_INDEX(ipos, type)].color == -1 ) { const Garnet::IVInstruction* dictCur = &Garnet::Dictionary::findByIVName(iv[ipos].label); ipos = (out_edges(ipos, iv).first + dictCur->pp[type].input[0] / NUM_PP_PER_FILTER)->m_target; type = dictCur->pp[type].input[0] % NUM_PP_PER_FILTER; } // Add an edge. add_edge(MAKE_PP_INDEX(u, t), MAKE_PP_INDEX(ipos, type), pg); } } } #undef ADD_SINK_EDGE } // 3. Remove introns. // Remove all vertices under non-Sink roots. if ( conf.read<bool>("/convertIVGraphToPPEGraph/Remove Introns/ShouldRemoveIntrons") ) { // 3.1 Find sink roots. std::stack<PVertex> q; // Non-intron vertices. std::set<PVertex> mark_v; // A vertex is an intron if it is not in mark_v. std::set<PEdge> mark_e; // An edge is an intron if it is not in mark_e. auto pg_vertices = vertices(pg); auto pg_edges = edges(pg); for (auto it = pg_vertices.first; it != pg_vertices.second; it++) { if ( IS_RES(pg[*it].type) && pg[*it].color != -1 ) { // move instruction for sink. mark_v.insert(*it); q.push(*it); } } // 3.2 Mark vertices and edges directly or indirectly connected to sink roots. while ( !q.empty() ) { PVertex pg_u = q.top(); q.pop(); // Mark the vertex as a non-intron. mark_v.insert(pg_u); // Mark edges from this vertex as non-introns. auto edges = out_edges(pg_u, pg); for_each(edges.first, edges.second, [&] (const PEdge& pg_e) { // Mark it is an important edge. mark_e.insert(pg_e); q.push(pg_e.m_target); }); } // 3.3 Make a new PPEGraph by copying V and E from the orignal except introns. PPEGraph pg_new; std::map<PVertex, PVertex> mapper; // <K,V>=<pg vertex, pg_new vertex> for_each(mark_v.begin(), mark_v.end(), [&] (const PVertex& pg_u) { PVertex pg_new_u = add_vertex(pg_new); pg_new[pg_new_u].label = pg[pg_u].label; pg_new[pg_new_u].type = pg[pg_u].type; pg_new[pg_new_u].color = pg[pg_u].color; mapper[pg_u] = pg_new_u; }); for_each(mark_v.begin(), mark_v.end(), [&] (const PVertex& pg_u) { auto edges = out_edges(pg_u, pg); for_each(edges.first, edges.second, [&] (const PEdge& pg_e) { add_edge(mapper[pg_e.m_source], mapper[pg_e.m_target], pg_new); }); }); // 3.4 Swap. pg.swap(pg_new); } trace.write("convertIVGraphToPPEGraph", "IVGraph to PPEGraph", "PPEGraph", pg); watch.stop(); if ( isLocationTrace() ) { std::cout << boost::format("\n[" __FUNCTION__ "] IVGraph to PPEGraph %.6fs") % watch.get(); std::cout << boost::format("\n[" __FUNCTION__ "] # of vertices: %6u") % num_vertices(pg); std::cout << boost::format("\n[" __FUNCTION__ "] # of edges: %6u") % num_edges(pg); std::cout << std::flush; } if ( isProcessTrace() ) { print_graph(pg, get(&PPEGraph::vertex_property_type::label, pg)); std::cout << "\n-----" << std::flush; } }
void TestDriver(typename itk::SmartPointer<TImage> originalImage, Mask::Pointer mask, const unsigned int patchHalfWidth) { /** Store the viewer here so that it is created in the GUI thread and persists. */ typedef BasicViewerWidget<TImage> BasicViewerWidgetType; std::shared_ptr<BasicViewerWidgetType> basicViewer(new BasicViewerWidgetType(originalImage, mask)); basicViewer->show(); typedef boost::grid_graph<2> VertexListGraphType; typedef DisplayVisitor<VertexListGraphType, TImage> DisplayVisitorType; std::shared_ptr<DisplayVisitorType> displayVisitor( new DisplayVisitorType(originalImage, mask, patchHalfWidth)); itk::ImageRegion<2> fullRegion = originalImage->GetLargestPossibleRegion(); // Blur the image typedef TImage BlurredImageType; // Usually the blurred image is the same type as the original image. typename BlurredImageType::Pointer blurredImage = BlurredImageType::New(); float blurVariance = 2.0f; MaskOperations::MaskedBlur(originalImage.GetPointer(), mask, blurVariance, blurredImage.GetPointer()); typedef ImagePatchPixelDescriptor<TImage> ImagePatchPixelDescriptorType; // Create the graph boost::array<std::size_t, 2> graphSideLengths = { { fullRegion.GetSize()[0], fullRegion.GetSize()[1] } }; std::shared_ptr<VertexListGraphType> graph(new VertexListGraphType(graphSideLengths)); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; std::shared_ptr<IndexMapType> indexMap(new IndexMapType(get(boost::vertex_index, *graph))); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType; std::shared_ptr<ImagePatchDescriptorMapType> imagePatchDescriptorMap( new ImagePatchDescriptorMapType(num_vertices(*graph), *indexMap)); // Queue typedef IndirectPriorityQueue<VertexListGraphType> BoundaryNodeQueueType; std::shared_ptr<BoundaryNodeQueueType> boundaryNodeQueue(new BoundaryNodeQueueType(*graph)); // Create the descriptor visitor typedef ImagePatchDescriptorVisitor<VertexListGraphType, TImage, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; std::shared_ptr<ImagePatchDescriptorVisitorType> imagePatchDescriptorVisitor( new ImagePatchDescriptorVisitorType(originalImage, mask, *imagePatchDescriptorMap, patchHalfWidth)); // If the hole is less than 15% of the patch, always accept the initial best match typedef HoleSizeAcceptanceVisitor<VertexListGraphType> HoleSizeAcceptanceVisitorType; std::shared_ptr<HoleSizeAcceptanceVisitorType> holeSizeAcceptanceVisitor(new HoleSizeAcceptanceVisitorType(mask, patchHalfWidth, .15)); // Create the priority function typedef PriorityCriminisi<TImage> PriorityType; std::shared_ptr<PriorityType> priorityFunction( new PriorityType(blurredImage, mask, patchHalfWidth)); // Create the inpainting visitor typedef InpaintingVisitor<VertexListGraphType, BoundaryNodeQueueType, ImagePatchDescriptorVisitorType, HoleSizeAcceptanceVisitorType, PriorityType> InpaintingVisitorType; std::shared_ptr<InpaintingVisitorType> inpaintingVisitor( new InpaintingVisitorType(mask, boundaryNodeQueue, imagePatchDescriptorVisitor, holeSizeAcceptanceVisitor, priorityFunction, patchHalfWidth, "InpaintingVisitor")); typedef SumSquaredPixelDifference<typename TImage::PixelType> PixelDifferenceType; typedef ImagePatchDifference<ImagePatchPixelDescriptorType, PixelDifferenceType > ImagePatchDifferenceType; // Create the nearest neighbor finders typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, ImagePatchDifferenceType > KNNSearchType; unsigned int numberOfKNN = 100; std::shared_ptr<KNNSearchType> knnSearch(new KNNSearchType(*imagePatchDescriptorMap, numberOfKNN)); // Run the remaining inpainting with interaction std::cout << "Running inpainting..." << std::endl; // QtConcurrent::run(boost::bind(InpaintingAlgorithmWithVerification< // VertexListGraphType, CompositeInpaintingVisitorType, // BoundaryNodeQueueType, KNNSearchType, BestSearchType, // ManualSearchType, CompositePatchInpainter>, // graph, compositeInpaintingVisitor, boundaryNodeQueue, knnSearch, // bestSearch, manualSearchBest, compositeInpainter)); // QtConcurrent::run(boost::bind(TestDriverFunction< // VertexListGraphType, CompositeInpaintingVisitorType, // BoundaryNodeQueueType, KNNSearchType, BestSearchType, // ManualSearchType, CompositePatchInpainter>, // graph, compositeInpaintingVisitor, boundaryNodeQueue, knnSearch, // bestSearch, manualSearchBest, compositeInpainter)); QtConcurrent::run(boost::bind(TestDriverFunction< VertexListGraphType, InpaintingVisitorType, BoundaryNodeQueueType, KNNSearchType>, graph, inpaintingVisitor, boundaryNodeQueue, knnSearch)); // QtConcurrent::run(boost::bind(TestDriverFunction< // VertexListGraphType, CompositeInpaintingVisitorType, // BoundaryNodeQueueType>, // graph, compositeInpaintingVisitor, boundaryNodeQueue)); // QtConcurrent::run(boost::bind(TestDriverFunction< // VertexListGraphType, CompositeInpaintingVisitorType>, // graph, compositeInpaintingVisitor)); // QtConcurrent::run(boost::bind(TestDriverFunction<VertexListGraphType>, graph)); }
transitive_reduction(const Graph& g, GraphTR& tr, G_to_TR_VertexMap g_to_tr_map, VertexIndexMap g_index_map ) { typedef typename graph_traits<Graph>::vertex_descriptor Vertex; typedef typename graph_traits<Graph>::vertex_iterator VertexIterator; typedef typename std::vector<Vertex>::size_type size_type; std::vector<Vertex> topo_order; topological_sort(g, std::back_inserter(topo_order)); std::vector<size_type> topo_number_storage(num_vertices(g)); iterator_property_map<size_type*, VertexIndexMap, size_type, size_type&> topo_number( &topo_number_storage[0], g_index_map ); { typename std::vector<Vertex>::reverse_iterator it = topo_order.rbegin(); size_type n = 0; for(; it != topo_order.rend(); ++it,++n ) { topo_number[ *it ] = n; } } std::vector< std::vector< bool > > edge_in_closure(num_vertices(g), std::vector<bool>( num_vertices(g), false)); { typename std::vector<Vertex>::reverse_iterator it = topo_order.rbegin(); for( ; it != topo_order.rend(); ++it ) { g_to_tr_map[*it] = add_vertex(tr); } } typename std::vector<Vertex>::iterator it = topo_order.begin(), end = topo_order.end(); for( ; it != end; ++it ) { size_type i = topo_number[ *it ]; edge_in_closure[i][i] = true; std::vector<Vertex> neighbors; //I have to collect the successors of *it and traverse them in //ascending topological order. I didn't know a better way, how to //do that. So what I'm doint is, collection the successors of *it here { typename Graph::out_edge_iterator oi,oi_end; for( tie(oi, oi_end) = out_edges( *it, g ); oi != oi_end; ++oi ) { neighbors.push_back( target( *oi, g ) ); } } { //and run through all vertices in topological order typename std::vector<Vertex>::reverse_iterator rit = topo_order.rbegin(); rend = topo_order.rend(); for(; rit != rend; ++rit ) { //looking if they are successors of *it if( std::find( neighbors.begin(), neighbors.end(), *rit) != neighbors.end() ) { size_type j = topo_number[ *rit ]; if( not edge_in_closure[i][j] ) { for(size_type k = j; k < num_vertices(g); ++k) { if( not edge_in_closure[i][k] ) { //here we need edge_in_closure to be in topological order, edge_in_closure[i][k] = edge_in_closure[j][k]; } } //therefore we only access edge_in_closure only through //topo_number property_map add_edge(g_to_tr_map[*it], g_to_tr_map[*rit], tr); } //if ( not edge_in_ } //if (find ( } //for( typename vector<Vertex>::reverse_iterator } // { } //for( typename vector<Vertex>::iterator } //void transitive_reduction
int main(int argc, char *argv[]) { // Verify arguments if(argc != 5) { std::cerr << "Required arguments: image.png imageMask.mask patchHalfWidth targetPatch.png" << std::endl; std::cerr << "Input arguments: "; for(int i = 1; i < argc; ++i) { std::cerr << argv[i] << " "; } return EXIT_FAILURE; } // Parse arguments std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::stringstream ssPatchHalfWidth; ssPatchHalfWidth << argv[3]; unsigned int patchHalfWidth = 0; ssPatchHalfWidth >> patchHalfWidth; std::string targetPatchFileName = argv[4]; // Output arguments std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "Reading mask: " << maskFilename << std::endl; std::cout << "Patch half width: " << patchHalfWidth << std::endl; std::cout << "targetPatchFileName: " << targetPatchFileName << std::endl; typedef itk::Image<itk::CovariantVector<int, 3>, 2> OriginalImageType; typedef itk::ImageFileReader<OriginalImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); OriginalImageType* originalImage = imageReader->GetOutput(); Mask::Pointer mask = Mask::New(); mask->Read(maskFilename); itk::ImageRegion<2> fullRegion = originalImage->GetLargestPossibleRegion(); // Blur the image // typedef TImage BlurredImageType; // Usually the blurred image is the same type as the original image. // typename BlurredImageType::Pointer blurredImage = BlurredImageType::New(); // float blurVariance = 2.0f; //// float blurVariance = 1.2f; // MaskOperations::MaskedBlur(originalImage.GetPointer(), mask, blurVariance, blurredImage.GetPointer()); // ITKHelpers::WriteRGBImage(blurredImage.GetPointer(), "BlurredImage.png"); typedef ImagePatchPixelDescriptor<OriginalImageType> ImagePatchPixelDescriptorType; // Create the graph typedef boost::grid_graph<2> VertexListGraphType; boost::array<std::size_t, 2> graphSideLengths = { { fullRegion.GetSize()[0], fullRegion.GetSize()[1] } }; std::shared_ptr<VertexListGraphType> graph(new VertexListGraphType(graphSideLengths)); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; typedef boost::graph_traits<VertexListGraphType>::vertex_iterator VertexIteratorType; // Queue typedef IndirectPriorityQueue<VertexListGraphType> BoundaryNodeQueueType; std::shared_ptr<BoundaryNodeQueueType> boundaryNodeQueue(new BoundaryNodeQueueType(*graph)); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, BoundaryNodeQueueType::IndexMapType> ImagePatchDescriptorMapType; std::shared_ptr<ImagePatchDescriptorMapType> imagePatchDescriptorMap(new ImagePatchDescriptorMapType(num_vertices(*graph), *(boundaryNodeQueue->GetIndexMap()))); // Create the descriptor visitor typedef ImagePatchDescriptorVisitor<VertexListGraphType, OriginalImageType, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; std::shared_ptr<ImagePatchDescriptorVisitorType> imagePatchDescriptorVisitor(new ImagePatchDescriptorVisitorType(originalImage, mask, // ImagePatchDescriptorVisitorType(blurredImage.GetPointer(), mask, imagePatchDescriptorMap, patchHalfWidth)); // Create the inpainting visitor // typedef InpaintingVisitor<VertexListGraphType, BoundaryNodeQueueType, // ImagePatchDescriptorVisitorType, AcceptanceVisitorType, PriorityType> // InpaintingVisitorType; // std::shared_ptr<InpaintingVisitorType> inpaintingVisitor(new InpaintingVisitorType(mask, boundaryNodeQueue, // imagePatchDescriptorVisitor, acceptanceVisitor, // priorityFunction, patchHalfWidth, "InpaintingVisitor")); // inpaintingVisitor->SetAllowNewPatches(false); // // Initialize the boundary node queue from the user provided mask image. // InitializeFromMaskImage<InpaintingVisitorType, VertexDescriptorType>(mask, inpaintingVisitor.get()); // // Create the nearest neighbor finder // typedef ImagePatchDifference<ImagePatchPixelDescriptorType, // SumSquaredPixelDifference<typename TImage::PixelType> > PatchDifferenceType; // // Write top patch grid at each iteration. To do this, we need a KNNSearcher // // to pass a list of valid patches to the FirstAndWrite class. // typedef LinearSearchKNNProperty<ImagePatchDescriptorMapType, // PatchDifferenceType > KNNSearchType; // unsigned int knn = 100; // std::shared_ptr<KNNSearchType> knnSearch(new KNNSearchType(imagePatchDescriptorMap, knn)); // typedef LinearSearchBestFirstAndWrite<ImagePatchDescriptorMapType, TImage, // PatchDifferenceType> BestSearchType; // std::shared_ptr<BestSearchType> linearSearchBest( // new BestSearchType(*imagePatchDescriptorMap, originalImage, mask)); //// typedef KNNBestWrapper<KNNSearchType, BestSearchType> KNNWrapperType; //// std::shared_ptr<KNNWrapperType> knnWrapper(new KNNWrapperType(knnSearch, //// linearSearchBest)); return EXIT_SUCCESS; }
plim_program compile_for_plim( const mig_graph& mig, const properties::ptr& settings, const properties::ptr& statistics ) { /* settings */ const auto verbose = get( settings, "verbose", false ); const auto progress = get( settings, "progress", false ); const auto enable_cost_function = get( settings, "enable_cost_function", true ); const auto generator_strategy = get( settings, "generator_strategy", 0u ); /* 0u: LIFO, 1u: FIFO */ /* timing */ properties_timer t( statistics ); plim_program program; const auto& info = mig_info( mig ); boost::dynamic_bitset<> computed( num_vertices( mig ) ); std::unordered_map<mig_function, memristor_index> func_to_rram; auto_index_generator<memristor_index> memristor_generator( generator_strategy == 0u ? auto_index_generator<memristor_index>::request_strategy::lifo : auto_index_generator<memristor_index>::request_strategy::fifo ); /* constant and all PIs are computed */ computed.set( info.constant ); for ( const auto& input : info.inputs ) { computed.set( input ); func_to_rram.insert( {{input, false}, memristor_generator.request()} ); } /* keep a priority queue for candidates invariant: candidates elements' children are all computed */ compilation_compare cmp( mig, enable_cost_function ); std::priority_queue<mig_node, std::vector<mig_node>, compilation_compare> candidates( cmp ); /* find initial candidates */ for ( const auto& node : boost::make_iterator_range( vertices( mig ) ) ) { /* PI and constant cannot be candidate */ if ( out_degree( node, mig ) == 0 ) { continue; } if ( all_children_computed( node, mig, computed ) ) { candidates.push( node ); } } const auto parent_edges = precompute_ingoing_edges( mig ); null_stream ns; std::ostream null_out( &ns ); boost::progress_display show_progress( num_vertices( mig ), progress ? std::cout : null_out ); /* synthesis loop */ while ( !candidates.empty() ) { ++show_progress; /* pick the best candidate */ auto candidate = candidates.top(); candidates.pop(); L( "[i] compute node " << candidate ); /* perform computation (e.g. mark which RRAM is used for this node) */ const auto children = get_children( mig, candidate ); boost::dynamic_bitset<> children_compl( 3u ); for ( const auto& f : index( children ) ) { children_compl.set( f.index, f.value.complemented ); } /* indexes and registers */ auto i_src_pos = 3u, i_src_neg = 3u, i_dst = 3u; plim_program::operand_t src_pos; plim_program::operand_t src_neg; memristor_index dst; /* find the inverter */ /* if there is one inverter */ if ( children_compl.count() == 1u ) { i_src_neg = children_compl.find_first(); if ( children[i_src_neg].node == 0u ) { src_neg = false; } else { src_neg = func_to_rram.at( {children[i_src_neg].node, false} ); } } /* if there are more than one inverters, but one of them is a constant */ else if ( children_compl.count() > 1u && children[children_compl.find_first()].node == 0u ) { i_src_neg = children_compl.find_next( children_compl.find_first() ); src_neg = func_to_rram.at( {children[i_src_neg].node, false} ); } /* if there is no inverter but a constant */ else if ( children_compl.count() == 0u && children[0u].node == 0u ) { i_src_neg = 0u; src_neg = !children[0u].complemented; } /* if there are more than one inverters */ else if ( children_compl.count() > 1u ) { do /* in order to escape early */ { /* pick an input that has multiple fanout */ for ( auto i = 0u; i < 3u; ++i ) { if ( !children_compl[i] ) continue; if ( cmp.fanout_count( children[i].node ) > 1u ) { i_src_neg = i; src_neg = func_to_rram.at( {children[i_src_neg].node, false} ); break; } } if ( i_src_neg < 3u ) { break; } i_src_neg = children_compl.find_first(); src_neg = func_to_rram.at( {children[i_src_neg].node, false} ); } while ( false ); } /* if there is no inverter */ else { do /* in order to escape early */ { /* pick an input that has multiple fanout */ for ( auto i = 0u; i < 3u; ++i ) { const auto it_reg = func_to_rram.find( {children[i].node, true} ); if ( it_reg != func_to_rram.end() ) { i_src_neg = i; src_neg = it_reg->second; break; } } if ( i_src_neg < 3u ) { break; } /* pick an input that has multiple fanout */ for ( auto i = 0u; i < 3u; ++i ) { if ( cmp.fanout_count( children[i].node ) > 1u ) { i_src_neg = i; break; } } /* or pick the first one */ if ( i_src_neg == 3u ) { i_src_neg = 0u; } /* create new register for inversion */ const auto inv_result = memristor_generator.request(); program.invert( inv_result, func_to_rram.at( {children[i_src_neg].node, false} ) ); func_to_rram.insert( {{children[i_src_neg].node, true}, inv_result} ); src_neg = inv_result; } while ( false ); } children_compl.reset( i_src_neg ); /* find the destination */ unsigned oa, ob; std::tie( oa, ob ) = three_without( i_src_neg ); /* if there is a child with one fan-out */ /* check whether they fulfill the requirements (non-constant and one fan-out) */ const auto oa_c = children[oa].node != 0u && cmp.fanout_count( children[oa].node ) == 1u; const auto ob_c = children[ob].node != 0u && cmp.fanout_count( children[ob].node ) == 1u; if ( oa_c || ob_c ) { /* first check for complemented cases (to avoid them for last operand) */ std::unordered_map<mig_function, memristor_index>::const_iterator it; if ( oa_c && children[oa].complemented && ( it = func_to_rram.find( {children[oa].node, true} ) ) != func_to_rram.end() ) { i_dst = oa; dst = it->second; } else if ( ob_c && children[ob].complemented && ( it = func_to_rram.find( {children[ob].node, true} ) ) != func_to_rram.end() ) { i_dst = ob; dst = it->second; } else if ( oa_c && !children[oa].complemented ) { i_dst = oa; dst = func_to_rram.at( {children[oa].node, false} ); } else if ( ob_c && !children[ob].complemented ) { i_dst = ob; dst = func_to_rram.at( {children[ob].node, false} ); } } /* no destination found yet? */ if ( i_dst == 3u ) { /* create new work RRAM */ dst = memristor_generator.request(); /* is there a constant (if, then it's the first one) */ if ( children[oa].node == 0u ) { i_dst = oa; program.read_constant( dst, children[oa].complemented ); } /* is there another inverter, then load it with that one? */ else if ( children_compl.count() > 0u ) { i_dst = children_compl.find_first(); program.invert( dst, func_to_rram.at( {children[i_dst].node, false} ) ); } /* otherwise, pick first one */ else { i_dst = oa; program.assign( dst, func_to_rram.at( {children[i_dst].node, false} ) ); } } /* positive operand */ i_src_pos = 3u - i_src_neg - i_dst; const auto node = children[i_src_pos].node; if ( node == 0u ) { src_pos = children[i_src_pos].complemented; } else if ( children[i_src_pos].complemented ) { const auto it_reg = func_to_rram.find( {node, true} ); if ( it_reg == func_to_rram.end() ) { /* create new register for inversion */ const auto inv_result = memristor_generator.request(); program.invert( inv_result, func_to_rram.at( {node, false} ) ); func_to_rram.insert( {{node, true}, inv_result} ); src_pos = inv_result; } else { src_pos = it_reg->second; } } else { src_pos = func_to_rram.at( {node, false} ); } program.compute( dst, src_pos, src_neg ); func_to_rram.insert( {{candidate, false}, dst} ); /* free free registers */ for ( const auto& c : children ) { if ( cmp.remove_fanout( c.node ) == 0u && c.node != 0u ) { const auto reg = func_to_rram.at( {c.node, false} ); if ( reg != dst ) { memristor_generator.release( reg ); } const auto it_reg = func_to_rram.find( {c.node, true} ); if ( it_reg != func_to_rram.end() && it_reg->second != dst ) { memristor_generator.release( it_reg->second ); } } } /* update computed and find new candidates */ computed.set( candidate ); const auto it = parent_edges.find( candidate ); if ( it != parent_edges.end() ) /* if it has parents */ { for ( const auto& e : it->second ) { const auto parent = boost::source( e, mig ); if ( !computed[parent] && all_children_computed( parent, mig, computed ) ) { candidates.push( parent ); } } } L( " - src_pos: " << i_src_pos << std::endl << " - src_neg: " << i_src_neg << std::endl << " - dst: " << i_dst << std::endl ); } set( statistics, "step_count", (int)program.step_count() ); set( statistics, "rram_count", (int)program.rram_count() ); std::vector<int> write_counts( program.write_counts().begin(), program.write_counts().end() ); set( statistics, "write_counts", write_counts ); return program; }
abc::Gia_Man_t* cirkit_to_gia( const aig_graph& aig ) { const auto& info = aig_info( aig ); const unsigned _num_inputs = info.inputs.size(); const unsigned _num_outputs = info.outputs.size(); const unsigned _num_latches = info.cis.size(); const unsigned _num_vertices = num_vertices( aig ) - 1u; const unsigned _num_gates = _num_vertices - _num_latches - _num_inputs; assert( _num_vertices == _num_inputs + _num_latches + _num_gates ); /* allocate an empty aig in abc */ abc::Gia_Man_t * gia = abc::Gia_ManStart( _num_vertices + _num_latches + _num_outputs + 1u ); gia->nConstrs = 0; gia->pName = strcpy( (char*)malloc( sizeof( char ) * ( info.model_name.size() + 1u ) ), info.model_name.c_str() ); std::vector< int > node_to_obj( boost::num_vertices( aig ) ); node_to_obj[0] = 0; /* inputs */ assert( !gia->vNamesIn ); gia->vNamesIn = abc::Vec_PtrStart( info.inputs.size() ); for ( const auto& input : index( info.inputs ) ) { const int obj = abc::Gia_ManAppendCi( gia ); node_to_obj[input.value] = abc::Abc_Lit2Var( obj ); const auto name = info.node_names.at( input.value ); abc::Vec_PtrSetEntry( gia->vNamesIn, input.index, strcpy( (char*)malloc( sizeof( char ) * ( name.size() + 1u ) ), name.c_str() ) ); } /* latches */ assert( info.cis.size() == info.cos.size() ); assert( _num_latches == 0u ); /* and gates */ std::vector<unsigned> topsort( boost::num_vertices( aig ) ); boost::topological_sort( aig, topsort.begin() ); for ( const auto& node : topsort ) { if ( !boost::out_degree( node, aig ) ) { continue; } const auto children = get_children( aig, node ); assert( children.size() == 2u ); const int obj = Gia_ManAppendAnd2_Simplified( gia, abc::Abc_Var2Lit( node_to_obj[children[0].node], children[0].complemented ), abc::Abc_Var2Lit( node_to_obj[children[1].node], children[1].complemented ) ); node_to_obj[node] = abc::Abc_Lit2Var( obj ); } /* outputs */ assert( !gia->vNamesOut ); gia->vNamesOut = abc::Vec_PtrStart( info.outputs.size() ); for ( const auto& output : index( info.outputs ) ) { abc::Gia_ManAppendCo( gia, abc::Abc_Var2Lit( node_to_obj[output.value.first.node], output.value.first.complemented ) ); const auto name = output.value.second; abc::Vec_PtrSetEntry( gia->vNamesOut, output.index, strcpy( (char*)malloc( sizeof( char ) * ( name.size() + 1u ) ), name.c_str() ) ); } return gia; }
int main(int, char *[]) { typedef float Weight; typedef boost::property<boost::edge_weight_t, Weight> WeightProperty; typedef boost::property<boost::vertex_name_t, std::string> NameProperty; typedef boost::adjacency_list < boost::listS, boost::vecS, boost::directedS, NameProperty, WeightProperty > Graph; typedef boost::graph_traits < Graph >::vertex_descriptor Vertex; typedef boost::property_map < Graph, boost::vertex_index_t >::type IndexMap; typedef boost::property_map < Graph, boost::vertex_name_t >::type NameMap; typedef boost::iterator_property_map < Vertex*, IndexMap, Vertex, Vertex& > PredecessorMap; typedef boost::iterator_property_map < Weight*, IndexMap, Weight, Weight& > DistanceMap; // Create a graph Graph g; // Add named vertices Vertex v0 = add_vertex(std::string("v0"), g); Vertex v1 = add_vertex(std::string("v1"), g); Vertex v2 = add_vertex(std::string("v2"), g); Vertex v3 = add_vertex(std::string("v3"), g); // Add weighted edges Weight weight0 = 5; Weight weight1 = 3; Weight weight2 = 2; Weight weight3 = 4; add_edge(v0, v1, weight0, g); add_edge(v1, v3, weight1, g); add_edge(v0, v2, weight2, g); add_edge(v2, v3, weight3, g); // At this point the graph is /* v0 . / \ 2 / \ / . v2 5/ \ / \ 4 / \ v1----------- v3 3 */ // Create things for Dijkstra std::vector<Vertex> predecessors(num_vertices(g)); // To store parents std::vector<Weight> distances(num_vertices(g)); // To store distances /* works ////////////// IndexMap indexMap = get(boost::vertex_index, g); PredecessorMap predecessorMap(&predecessors[0], indexMap); DistanceMap distanceMap(&distances[0], indexMap); // Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap).distance_map(distanceMap)); ////////////// */ ////////////// IndexMap indexMap = get(boost::vertex_index, g); DistanceMap distanceMap(&distances[0], indexMap); PredecessorMap predecessorMap(&predecessors[0], indexMap); boost::predecessor_map(predecessorMap).distance_map(distanceMap); // Compute shortest paths from v0 to all vertices, and store the output in predecessors and distances boost::dijkstra_shortest_paths(g, v0, boost::predecessor_map(predecessorMap)); ////////////// // Output results std::cout << "distances and parents:" << std::endl; NameMap nameMap = get(boost::vertex_name, g); BGL_FORALL_VERTICES(v, g, Graph) { std::cout << "distance(" << nameMap[v0] << ", " << nameMap[v] << ") = " << distanceMap[v] << ", "; std::cout << "predecessor(" << nameMap[v] << ") = " << nameMap[predecessorMap[v]] << std::endl; }
// Run with: Data/trashcan.mha Data/trashcan_mask.mha 15 Data/trashcan.vtp Intensity filled.mha int main(int argc, char *argv[]) { // Verify arguments if(argc != 6) { std::cerr << "Required arguments: image.mha imageMask.mha patch_half_width normals.vts output.mha" << std::endl; std::cerr << "Input arguments: "; for(int i = 1; i < argc; ++i) { std::cerr << argv[i] << " "; } return EXIT_FAILURE; } // Parse arguments std::string imageFilename = argv[1]; std::string maskFilename = argv[2]; std::stringstream ssPatchRadius; ssPatchRadius << argv[3]; unsigned int patch_half_width = 0; ssPatchRadius >> patch_half_width; std::string normalsFileName = argv[4]; std::string outputFilename = argv[5]; // Output arguments std::cout << "Reading image: " << imageFilename << std::endl; std::cout << "Reading mask: " << maskFilename << std::endl; std::cout << "Patch half width: " << patch_half_width << std::endl; std::cout << "Reading normals: " << normalsFileName << std::endl; std::cout << "Output: " << outputFilename << std::endl; vtkSmartPointer<vtkXMLStructuredGridReader> structuredGridReader = vtkSmartPointer<vtkXMLStructuredGridReader>::New(); structuredGridReader->SetFileName(normalsFileName.c_str()); structuredGridReader->Update(); typedef FloatVectorImageType ImageType; typedef itk::ImageFileReader<ImageType> ImageReaderType; ImageReaderType::Pointer imageReader = ImageReaderType::New(); imageReader->SetFileName(imageFilename); imageReader->Update(); ImageType::Pointer image = ImageType::New(); ITKHelpers::DeepCopy(imageReader->GetOutput(), image.GetPointer()); Mask::Pointer mask = Mask::New(); mask->Read(maskFilename); std::cout << "hole pixels: " << mask->CountHolePixels() << std::endl; std::cout << "valid pixels: " << mask->CountValidPixels() << std::endl; typedef ImagePatchPixelDescriptor<ImageType> ImagePatchPixelDescriptorType; typedef FeatureVectorPixelDescriptor FeatureVectorPixelDescriptorType; // Create the graph typedef boost::grid_graph<2> VertexListGraphType; boost::array<std::size_t, 2> graphSideLengths = { { imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[0], imageReader->GetOutput()->GetLargestPossibleRegion().GetSize()[1] } }; VertexListGraphType graph(graphSideLengths); typedef boost::graph_traits<VertexListGraphType>::vertex_descriptor VertexDescriptorType; // Get the index map typedef boost::property_map<VertexListGraphType, boost::vertex_index_t>::const_type IndexMapType; IndexMapType indexMap(get(boost::vertex_index, graph)); // Create the priority map typedef boost::vector_property_map<float, IndexMapType> PriorityMapType; PriorityMapType priorityMap(num_vertices(graph), indexMap); // Create the node fill status map. Each pixel is either filled (true) or not filled (false). typedef boost::vector_property_map<bool, IndexMapType> FillStatusMapType; FillStatusMapType fillStatusMap(num_vertices(graph), indexMap); // Create the boundary status map. A node is on the current boundary if this property is true. // This property helps the boundaryNodeQueue because we can mark here if a node has become no longer // part of the boundary, so when the queue is popped we can check this property to see if it should // actually be processed. typedef boost::vector_property_map<bool, IndexMapType> BoundaryStatusMapType; BoundaryStatusMapType boundaryStatusMap(num_vertices(graph), indexMap); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<ImagePatchPixelDescriptorType, IndexMapType> ImagePatchDescriptorMapType; ImagePatchDescriptorMapType imagePatchDescriptorMap(num_vertices(graph), indexMap); // Create the descriptor map. This is where the data for each pixel is stored. typedef boost::vector_property_map<FeatureVectorPixelDescriptorType, IndexMapType> FeatureVectorDescriptorMapType; FeatureVectorDescriptorMapType featureVectorDescriptorMap(num_vertices(graph), indexMap); // Create the patch inpainter. The inpainter needs to know the status of each pixel to determine if they should be inpainted. typedef MaskedGridPatchInpainter<FillStatusMapType> InpainterType; InpainterType patchInpainter(patch_half_width, fillStatusMap); // Create the priority function typedef PriorityRandom PriorityType; PriorityType priorityFunction; // Create the boundary node queue. The priority of each node is used to order the queue. typedef boost::vector_property_map<std::size_t, IndexMapType> IndexInHeapMap; IndexInHeapMap index_in_heap(indexMap); // Create the priority compare functor typedef std::less<float> PriorityCompareType; PriorityCompareType lessThanFunctor; typedef boost::d_ary_heap_indirect<VertexDescriptorType, 4, IndexInHeapMap, PriorityMapType, PriorityCompareType> BoundaryNodeQueueType; BoundaryNodeQueueType boundaryNodeQueue(priorityMap, index_in_heap, lessThanFunctor); // Create the descriptor visitors typedef FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitor<VertexListGraphType, FeatureVectorDescriptorMapType> FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitorType; FeatureVectorPrecomputedStructuredGridNormalsDescriptorVisitorType featureVectorPrecomputedStructuredGridNormalsDescriptorVisitor(featureVectorDescriptorMap, structuredGridReader->GetOutput()); typedef ImagePatchDescriptorVisitor<VertexListGraphType, ImageType, ImagePatchDescriptorMapType> ImagePatchDescriptorVisitorType; ImagePatchDescriptorVisitorType imagePatchDescriptorVisitor(image, mask, imagePatchDescriptorMap, patch_half_width); typedef CompositeDescriptorVisitor<VertexListGraphType> CompositeDescriptorVisitorType; CompositeDescriptorVisitorType compositeDescriptorVisitor; compositeDescriptorVisitor.AddVisitor(&imagePatchDescriptorVisitor); compositeDescriptorVisitor.AddVisitor(&featureVectorPrecomputedStructuredGridNormalsDescriptorVisitor); // Create the inpainting visitor typedef InpaintingVisitor<VertexListGraphType, ImageType, BoundaryNodeQueueType, FillStatusMapType, CompositeDescriptorVisitorType, PriorityType, PriorityMapType, BoundaryStatusMapType> InpaintingVisitorType; InpaintingVisitorType inpaintingVisitor(image, mask, boundaryNodeQueue, fillStatusMap, compositeDescriptorVisitor, priorityMap, &priorityFunction, patch_half_width, boundaryStatusMap); InitializePriority(mask, boundaryNodeQueue, priorityMap, &priorityFunction, boundaryStatusMap); // Initialize the boundary node queue from the user provided mask image. InitializeFromMaskImage(mask, &inpaintingVisitor, graph, fillStatusMap); std::cout << "PatchBasedInpaintingNonInteractive: There are " << boundaryNodeQueue.size() << " nodes in the boundaryNodeQueue" << std::endl; // Create the nearest neighbor finder // typedef LinearSearchKNNProperty<FeatureVectorDescriptorMapType, FeatureVectorAngleDifference> KNNSearchType; // KNNSearchType linearSearchKNN(featureVectorDescriptorMap); typedef LinearSearchCriteriaProperty<FeatureVectorDescriptorMapType, FeatureVectorAngleDifference> ThresholdSearchType; //float maximumAngle = 0.34906585; // ~ 20 degrees float maximumAngle = 0.15; // ~ 10 degrees //float maximumAngle = 0.08; // ~ 5 degrees (this seems to be too strict) ThresholdSearchType thresholdSearchType(featureVectorDescriptorMap, maximumAngle); typedef LinearSearchBestProperty<ImagePatchDescriptorMapType, ImagePatchDifference<ImagePatchPixelDescriptorType> > BestSearchType; BestSearchType linearSearchBest(imagePatchDescriptorMap); TwoStepNearestNeighbor<ThresholdSearchType, BestSearchType> twoStepNearestNeighbor(thresholdSearchType, linearSearchBest); // Perform the inpainting std::cout << "Performing inpainting...: " << std::endl; inpainting_loop(graph, inpaintingVisitor, boundaryStatusMap, boundaryNodeQueue, twoStepNearestNeighbor, patchInpainter); HelpersOutput::WriteImage<ImageType>(image, outputFilename); return EXIT_SUCCESS; }
void component_leaders( Graph& g, const ComponentMap& C, dynamic_array<typename graph_traits<Graph>::vertex_descriptor>& leaders) { #pragma mta noalias g #pragma mta noalias C #pragma mta noalias leaders typedef typename graph_traits<Graph>::size_type size_type; typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor; typedef typename graph_traits<Graph>::thread_vertex_iterator thread_vertex_iterator; size_type order = num_vertices(g); size_type* rcount = (size_type*) malloc(order * sizeof(size_type)); for (size_type i = 0; i < order; ++i) rcount[i] = 0; size_type stream_id = 0; size_type num_streams = 1; // Count the number of vertices in each component. #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(order, stream_id, num_streams); size_type end_pos = end_block_range(order, stream_id, num_streams); thread_vertex_iterator verts = thread_vertices(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++verts) { mt_incr(rcount[C[*verts]], 1); } } size_type num_components = 0; // Count the number of components. #pragma mta assert nodep for (size_type i = 0; i < order; ++i) { if (rcount[i] > 0) mt_incr(num_components, 1); } // Resize the leaders array. leaders.resize(num_components); num_components = 0; // Put the leaders for each component in the leaders array. #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(order, stream_id, num_streams); size_type end_pos = end_block_range(order, stream_id, num_streams); thread_vertex_iterator verts = thread_vertices(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++verts) { if (rcount[start_pos] > 0) { size_type pos = mt_incr(num_components, 1); leaders[pos] = *verts; } } } free(rcount); }
void reduceTransitEdges(const std::vector<Primitive*>& vecPrimitive, std::vector<RelationEdge>& vecRelationEdge, RelationEdge::RelationEdgeType relationType, Graph& g) { std::sort(vecRelationEdge.begin(), vecRelationEdge.end()); std::map<GraphVertex, RelationVertex> mapVertex; for (size_t i = 0, iEnd = vecRelationEdge.size(); i < iEnd; ++ i) { GraphVertex u = vecRelationEdge[i].getTarget().getIdx(); GraphVertex v = vecRelationEdge[i].getSource().getIdx(); mapVertex[u] = vecRelationEdge[i].getTarget(); mapVertex[v] = vecRelationEdge[i].getSource(); add_edge(u, v, EdgeProp(relationType), g); } std::vector<GraphVertex> component(num_vertices(g)); size_t numComponent = connected_components(g, &component[0]); std::map<size_t, std::vector<size_t> > mapComponent; for (size_t i = 0, iEnd = component.size(); i < iEnd; ++ i) { mapComponent[component[i]].push_back(i); } vecRelationEdge.clear(); for (std::map<size_t, std::vector<size_t> >::const_iterator it = mapComponent.begin(); it != mapComponent.end(); ++ it) { const std::vector<size_t>& vecComponent = it->second; if (vecComponent.size() < 2) { continue; } GraphVertex u = vecComponent[0]; for (size_t i = 1, iEnd = vecComponent.size(); i < iEnd; ++ i) { GraphVertex v = vecComponent[i]; RelationEdge relationEdge(relationType, mapVertex[v], mapVertex[u], 1.0); GlobFit::computeEdgeScore(relationEdge, vecPrimitive); vecRelationEdge.push_back(relationEdge); } } std::sort(vecRelationEdge.begin(), vecRelationEdge.end()); if (vecRelationEdge.size() == 0) { return; } if (vecRelationEdge[0].getType() != RelationEdge::RET_EQUAL_ANGLE && vecRelationEdge[0].getType() != RelationEdge::RET_EQUAL_LENGTH) { return; } g.clear(); for (size_t i = 0, iEnd = vecPrimitive.size(); i < iEnd; ++ i) { RelationVertex relationVertex(i, vecPrimitive[i]->getIdx()); relationVertex.setParent(i); add_vertex(relationVertex, g); } std::vector<RelationEdge> vecRemainingEdge; std::vector<GraphVertex> vecPredecessor(vecPrimitive.size()); for (size_t i = 0, iEnd = vecRelationEdge.size(); i < iEnd; ++ i) { const RelationVertex& source = vecRelationEdge[i].getSource(); const RelationVertex& target = vecRelationEdge[i].getTarget(); bool sourceProduceLoop = willProduceLoop(vecPredecessor, source.getPrimitiveIdx1(), source.getPrimitiveIdx2(), g); bool targetProduceLoop = willProduceLoop(vecPredecessor, target.getPrimitiveIdx1(), target.getPrimitiveIdx2(), g); // this is too strong for avoiding conflicts, some compatible cases may be removed // TODO: deduce the right rules for edges with 4 primitives involved if (sourceProduceLoop || targetProduceLoop) { continue; } add_edge(source.getPrimitiveIdx1(), source.getPrimitiveIdx2(), g); add_edge(target.getPrimitiveIdx1(), target.getPrimitiveIdx2(), g); vecRemainingEdge.push_back(vecRelationEdge[i]); } vecRelationEdge = vecRemainingEdge; return; }
void connected_components(Graph& g, ComponentMap& result) { #pragma mta noalias g #pragma mta noalias result typedef typename graph_traits<Graph>::size_type size_type; typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor; typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor; typedef typename graph_traits<Graph>::thread_vertex_iterator thread_vertex_iterator; typedef typename graph_traits<Graph>::thread_edge_iterator thread_edge_iterator; size_type order = num_vertices(g); size_type size = num_edges(g); vertex_id_map<Graph> vid_map = get(_vertex_id_map, g); size_type stream_id = 0; size_type num_streams = 1; // Initialize each vertex to have itself as its leader. #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(order, stream_id, num_streams); size_type end_pos = end_block_range(order, stream_id, num_streams); thread_vertex_iterator verts = thread_vertices(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++verts) { put(result, *verts, start_pos); } } // Find the highest degree vertex. size_type* degrees = new size_type[order]; #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(order, stream_id, num_streams); size_type end_pos = end_block_range(order, stream_id, num_streams); thread_vertex_iterator verts = thread_vertices(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++verts) { degrees[start_pos] = out_degree(*verts, g); } } size_type max_deg_vert_id = 0; size_type maxdeg = degrees[0]; #pragma mta assert nodep for (size_type i = 1; i < order; i++) { if (degrees[i] > maxdeg) { maxdeg = degrees[i]; max_deg_vert_id = i; } } delete [] degrees; vertex_descriptor max_deg_vert = *(thread_vertices(max_deg_vert_id, g)); // Search from the highest degree vertex to label the giant component (GCC). detail::news_visitor<Graph, ComponentMap> nvis(result, max_deg_vert); breadth_first_search(g, max_deg_vert, nvis); size_type orphan_edges = 0; #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(size, stream_id, num_streams); size_type end_pos = end_block_range(size, stream_id, num_streams); size_type my_orphan_edges = 0; thread_edge_iterator tedgs = thread_edges(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++tedgs) { edge_descriptor e = *tedgs; vertex_descriptor u = source(e, g); vertex_descriptor v = target(e, g); if (result[u] != max_deg_vert_id || result[v] != max_deg_vert_id) { ++my_orphan_edges; } } mt_incr(orphan_edges, my_orphan_edges); } size_type next_index = 0; size_type* srcs = new size_type[orphan_edges]; size_type* dests = new size_type[orphan_edges]; #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(size, stream_id, num_streams); size_type end_pos = end_block_range(size, stream_id, num_streams); thread_edge_iterator tedgs = thread_edges(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++tedgs) { edge_descriptor e = *tedgs; vertex_descriptor u = source(e, g); vertex_descriptor v = target(e, g); if (result[u] != max_deg_vert_id || result[v] != max_deg_vert_id) { size_type my_ind = mt_incr(next_index, 1); srcs[my_ind] = get(vid_map, u); dests[my_ind] = get(vid_map, v); } } } edge_array_adapter<size_type> eaa(srcs, dests, order, orphan_edges); vertex_property_map<edge_array_adapter<size_type>, size_type> eaa_components(eaa); #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(order, stream_id, num_streams); size_type end_pos = end_block_range(order, stream_id, num_streams); thread_vertex_iterator verts = thread_vertices(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++verts) { vertex_descriptor v = *verts; eaa_components[v] = result[v]; } } shiloach_vishkin_no_init(eaa, eaa_components); #pragma mta for all streams stream_id of num_streams { size_type start_pos = begin_block_range(order, stream_id, num_streams); size_type end_pos = end_block_range(order, stream_id, num_streams); thread_vertex_iterator verts = thread_vertices(start_pos, g); for ( ; start_pos != end_pos; ++start_pos, ++verts) { vertex_descriptor v = *verts; result[v] = eaa_components[v]; } } delete [] srcs; delete [] dests; }
static void detectArticulationPoints(std::vector<RelationEdge>& vecRelationEdge, Graph& g) { for (size_t i = 0, iEnd = vecRelationEdge.size(); i < iEnd; ++ i) { RelationEdge& relationEdge = vecRelationEdge[i]; GraphVertex u = relationEdge.getSource().getIdx(); GraphVertex v = relationEdge.getTarget().getIdx(); add_edge(u, v, EdgeProp(relationEdge.getType(), relationEdge.getScore()), g); } removeIsolatedEdges(g); std::vector<GraphVertex> vecArticulationPoint; articulation_points(g, std::back_inserter(vecArticulationPoint)); while (!vecArticulationPoint.empty()) { GraphVertex nWeakestPoint = 0; double nMinWeight = std::numeric_limits<double>::max(); for (GraphVertex i = 0; i < vecArticulationPoint.size(); ++ i) { double nWeight = 0; std::pair<GraphOutEdgeItr, GraphOutEdgeItr> edgeItr = out_edges(vecArticulationPoint[i], g); for (GraphOutEdgeItr it = edgeItr.first; it != edgeItr.second; it ++) { nWeight += g[*it].score; } if (nWeight < nMinWeight) { nMinWeight = nWeight; nWeakestPoint = vecArticulationPoint[i]; } } std::map<GraphVertex, EdgeProp> mapVertex2Edge; std::pair<GraphOutEdgeItr, GraphOutEdgeItr> edgeItr = out_edges(nWeakestPoint, g); for (GraphOutEdgeItr it = edgeItr.first; it != edgeItr.second; it ++) { mapVertex2Edge[target(*it, g)] = g[*it]; } clear_vertex(nWeakestPoint, g); std::vector<GraphVertex> component(num_vertices(g)); size_t nComponentNum = connected_components(g, &component[0]); std::vector<double> vecWeight(nComponentNum, 0.0); std::vector<int> vecCount(nComponentNum, 0); for (std::map<GraphVertex, EdgeProp>::iterator it = mapVertex2Edge.begin(); it != mapVertex2Edge.end(); it ++) { vecWeight[component[it->first]] += it->second.score; vecCount[component[it->first]] ++; } for (size_t i = 0; i < nComponentNum; ++ i) { if (vecCount[i] != 0) { vecWeight[i] /= vecCount[i]; } } size_t nStrongestComponent = std::distance(vecWeight.begin(), std::max_element(vecWeight.begin(), vecWeight.end())); for (std::map<GraphVertex, EdgeProp>::iterator it = mapVertex2Edge.begin(); it != mapVertex2Edge.end(); it ++) { GraphVertex v = it->first; if (component[v] == nStrongestComponent) { add_edge(nWeakestPoint, v, mapVertex2Edge[v], g); } } removeIsolatedEdges(g); vecArticulationPoint.clear(); articulation_points(g, std::back_inserter(vecArticulationPoint)); } return; }
typename graph_traits<VertexListGraph>::degree_size_type edge_connectivity(VertexListGraph& g, OutputIterator disconnecting_set) { //------------------------------------------------------------------------- // Type Definitions typedef graph_traits<VertexListGraph> Traits; typedef typename Traits::vertex_iterator vertex_iterator; typedef typename Traits::edge_iterator edge_iterator; typedef typename Traits::out_edge_iterator out_edge_iterator; typedef typename Traits::vertex_descriptor vertex_descriptor; typedef typename Traits::degree_size_type degree_size_type; typedef color_traits<default_color_type> Color; typedef adjacency_list_traits<vecS, vecS, directedS> Tr; typedef typename Tr::edge_descriptor Tr_edge_desc; typedef adjacency_list<vecS, vecS, directedS, no_property, property<edge_capacity_t, degree_size_type, property<edge_residual_capacity_t, degree_size_type, property<edge_reverse_t, Tr_edge_desc> > > > FlowGraph; typedef typename graph_traits<FlowGraph>::edge_descriptor edge_descriptor; //------------------------------------------------------------------------- // Variable Declarations vertex_descriptor u, v, p, k; edge_descriptor e1, e2; bool inserted; vertex_iterator vi, vi_end; edge_iterator ei, ei_end; degree_size_type delta, alpha_star, alpha_S_k; std::set<vertex_descriptor> S, neighbor_S; std::vector<vertex_descriptor> S_star, non_neighbor_S; std::vector<default_color_type> color(num_vertices(g)); std::vector<edge_descriptor> pred(num_vertices(g)); //------------------------------------------------------------------------- // Create a network flow graph out of the undirected graph FlowGraph flow_g(num_vertices(g)); typename property_map<FlowGraph, edge_capacity_t>::type cap = get(edge_capacity, flow_g); typename property_map<FlowGraph, edge_residual_capacity_t>::type res_cap = get(edge_residual_capacity, flow_g); typename property_map<FlowGraph, edge_reverse_t>::type rev_edge = get(edge_reverse, flow_g); for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { u = source(*ei, g), v = target(*ei, g); tie(e1, inserted) = add_edge(u, v, flow_g); cap[e1] = 1; tie(e2, inserted) = add_edge(v, u, flow_g); cap[e2] = 1; // not sure about this rev_edge[e1] = e2; rev_edge[e2] = e1; } //------------------------------------------------------------------------- // The Algorithm tie(p, delta) = detail::min_degree_vertex(g); S_star.push_back(p); alpha_star = delta; S.insert(p); neighbor_S.insert(p); detail::neighbors(g, S.begin(), S.end(), std::inserter(neighbor_S, neighbor_S.begin())); std::set_difference(vertices(g).first, vertices(g).second, neighbor_S.begin(), neighbor_S.end(), std::back_inserter(non_neighbor_S)); while (!non_neighbor_S.empty()) { // at most n - 1 times k = non_neighbor_S.front(); alpha_S_k = edmonds_karp_max_flow (flow_g, p, k, cap, res_cap, rev_edge, &color[0], &pred[0]); if (alpha_S_k < alpha_star) { alpha_star = alpha_S_k; S_star.clear(); for (tie(vi, vi_end) = vertices(flow_g); vi != vi_end; ++vi) if (color[*vi] != Color::white()) S_star.push_back(*vi); } S.insert(k); neighbor_S.insert(k); detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin())); non_neighbor_S.clear(); std::set_difference(vertices(g).first, vertices(g).second, neighbor_S.begin(), neighbor_S.end(), std::back_inserter(non_neighbor_S)); } //------------------------------------------------------------------------- // Compute edges of the cut [S*, ~S*] std::vector<bool> in_S_star(num_vertices(g), false); typename std::vector<vertex_descriptor>::iterator si; for (si = S_star.begin(); si != S_star.end(); ++si) in_S_star[*si] = true; degree_size_type c = 0; for (si = S_star.begin(); si != S_star.end(); ++si) { out_edge_iterator ei, ei_end; for (tie(ei, ei_end) = out_edges(*si, g); ei != ei_end; ++ei) if (!in_S_star[target(*ei, g)]) { *disconnecting_set++ = *ei; ++c; } } return c; }
void planar_canonical_ordering(const Graph& g, PlanarEmbedding embedding, OutputIterator ordering, VertexIndexMap vm) { typedef typename graph_traits<Graph>::vertex_descriptor vertex_t; typedef typename graph_traits<Graph>::edge_descriptor edge_t; typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator_t; typedef typename graph_traits<Graph>::adjacency_iterator adjacency_iterator_t; typedef typename std::pair<vertex_t, vertex_t> vertex_pair_t; typedef typename property_traits<PlanarEmbedding>::value_type embedding_value_t; typedef typename embedding_value_t::const_iterator embedding_iterator_t; typedef iterator_property_map <typename std::vector<vertex_t>::iterator, VertexIndexMap> vertex_to_vertex_map_t; typedef iterator_property_map <typename std::vector<std::size_t>::iterator, VertexIndexMap> vertex_to_size_t_map_t; enum {PROCESSED, UNPROCESSED, ONE_NEIGHBOR_PROCESSED, READY_TO_BE_PROCESSED}; std::vector<vertex_t> processed_neighbor_vector(num_vertices(g)); vertex_to_vertex_map_t processed_neighbor (processed_neighbor_vector.begin(), vm); std::vector<std::size_t> status_vector(num_vertices(g), UNPROCESSED); vertex_to_size_t_map_t status(status_vector.begin(), vm); std::list<vertex_t> ready_to_be_processed; vertex_t first_vertex = *vertices(g).first; vertex_t second_vertex; adjacency_iterator_t ai, ai_end; for(tie(ai,ai_end) = adjacent_vertices(first_vertex,g); ai != ai_end; ++ai) { if (*ai == first_vertex) continue; second_vertex = *ai; break; } ready_to_be_processed.push_back(first_vertex); status[first_vertex] = READY_TO_BE_PROCESSED; ready_to_be_processed.push_back(second_vertex); status[second_vertex] = READY_TO_BE_PROCESSED; while(!ready_to_be_processed.empty()) { vertex_t u = ready_to_be_processed.front(); ready_to_be_processed.pop_front(); if (status[u] != READY_TO_BE_PROCESSED && u != second_vertex) continue; embedding_iterator_t ei, ei_start, ei_end; embedding_iterator_t next_edge_itr, prior_edge_itr; ei_start = embedding[u].begin(); ei_end = embedding[u].end(); prior_edge_itr = prior(ei_end); while(source(*prior_edge_itr, g) == target(*prior_edge_itr,g)) prior_edge_itr = prior(prior_edge_itr); for(ei = ei_start; ei != ei_end; ++ei) { edge_t e(*ei); // e = (u,v) next_edge_itr = next(ei) == ei_end ? ei_start : next(ei); vertex_t v = source(e,g) == u ? target(e,g) : source(e,g); vertex_t prior_vertex = source(*prior_edge_itr, g) == u ? target(*prior_edge_itr, g) : source(*prior_edge_itr, g); vertex_t next_vertex = source(*next_edge_itr, g) == u ? target(*next_edge_itr, g) : source(*next_edge_itr, g); // Need prior_vertex, u, v, and next_vertex to all be // distinct. This is possible, since the input graph is // triangulated. It'll be true all the time in a simple // graph, but loops and parallel edges cause some complications. if (prior_vertex == v || prior_vertex == u) { prior_edge_itr = ei; continue; } //Skip any self-loops if (u == v) continue; // Move next_edge_itr (and next_vertex) forwards // past any loops or parallel edges while (next_vertex == v || next_vertex == u) { next_edge_itr = next(next_edge_itr) == ei_end ? ei_start : next(next_edge_itr); next_vertex = source(*next_edge_itr, g) == u ? target(*next_edge_itr, g) : source(*next_edge_itr, g); } if (status[v] == UNPROCESSED) { status[v] = ONE_NEIGHBOR_PROCESSED; processed_neighbor[v] = u; } else if (status[v] == ONE_NEIGHBOR_PROCESSED) { vertex_t x = processed_neighbor[v]; //are edges (v,u) and (v,x) adjacent in the planar //embedding? if so, set status[v] = 1. otherwise, set //status[v] = 2. if ((next_vertex == x && !(first_vertex == u && second_vertex == x) ) || (prior_vertex == x && !(first_vertex == x && second_vertex == u) ) ) { status[v] = READY_TO_BE_PROCESSED; } else { status[v] = READY_TO_BE_PROCESSED + 1; } } else if (status[v] > ONE_NEIGHBOR_PROCESSED) { //check the two edges before and after (v,u) in the planar //embedding, and update status[v] accordingly bool processed_before = false; if (status[prior_vertex] == PROCESSED) processed_before = true; bool processed_after = false; if (status[next_vertex] == PROCESSED) processed_after = true; if (!processed_before && !processed_after) ++status[v]; else if (processed_before && processed_after) --status[v]; } if (status[v] == READY_TO_BE_PROCESSED) ready_to_be_processed.push_back(v); prior_edge_itr = ei; } status[u] = PROCESSED; *ordering = u; ++ordering; } }