示例#1
0
  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);

        }
      }  
示例#3
0
  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;
  }
示例#4
0
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

}
示例#6
0
文件: elch.hpp 项目: 2php/pcl
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);
  }
}
示例#7
0
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 );
  }
}
示例#8
0
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
示例#10
0
        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;
        }
示例#11
0
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;

}
示例#12
0
 vertex_descriptor goal() const {
   return vertex(num_vertices(m_grid)-1, m_grid);
 }
示例#13
0
 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);
 }
示例#14
0
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;
}
示例#15
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;
}
示例#21
0
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;
}
示例#22
0
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;
}
示例#23
0
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);
}
示例#26
0
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;
}
示例#28
0
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;
}
示例#29
0
  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;
  }
示例#30
-1
  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;
        
      }
    
  }