inline void
 dag_sp_dispatch2
   (const VertexListGraph& g,
    typename graph_traits<VertexListGraph>::vertex_descriptor s, 
    DistanceMap distance, WeightMap weight, ColorMap color, IndexMap /*id*/,
    DijkstraVisitor vis, const Params& params)
 {
   typedef typename property_traits<DistanceMap>::value_type D;
   dummy_property_map p_map;
   dag_shortest_paths
     (g, s, distance, weight, color, 
      choose_param(get_param(params, vertex_predecessor), p_map),
      vis, 
      choose_param(get_param(params, distance_compare_t()), std::less<D>()),
      choose_param(get_param(params, distance_combine_t()), closed_plus<D>()),
      choose_param(get_param(params, distance_inf_t()), 
                   (std::numeric_limits<D>::max)()),
      choose_param(get_param(params, distance_zero_t()), 
                   D()));
 }
Beispiel #2
0
static
depth findMaxWidth(const NGHolder &h, const SpecialEdgeFilter &filter,
                   NFAVertex src) {
    if (isLeafNode(src, h.g)) {
        return depth::unreachable();
    }

    if (hasReachableCycle(h, src)) {
        // There's a cycle reachable from this src, so we have inf width.
        return depth::infinity();
    }

    boost::filtered_graph<NFAGraph, SpecialEdgeFilter> g(h.g, filter);

    assert(hasCorrectlyNumberedVertices(h));
    const size_t num = num_vertices(h);
    vector<int> distance(num);
    vector<boost::default_color_type> colors(num);

    auto index_map = get(&NFAGraphVertexProps::index, g);

    // DAG shortest paths with negative edge weights.
    dag_shortest_paths(
        g, src,
        distance_map(make_iterator_property_map(distance.begin(), index_map))
            .weight_map(boost::make_constant_property<NFAEdge>(-1))
            .vertex_index_map(index_map)
            .color_map(make_iterator_property_map(colors.begin(), index_map)));

    depth acceptDepth, acceptEodDepth;
    if (colors.at(NODE_ACCEPT) == boost::white_color) {
        acceptDepth = depth::unreachable();
    } else {
        acceptDepth = -1 * distance.at(NODE_ACCEPT);
    }
    if (colors.at(NODE_ACCEPT_EOD) == boost::white_color) {
        acceptEodDepth = depth::unreachable();
    } else {
        acceptEodDepth = -1 * distance.at(NODE_ACCEPT_EOD);
    }

    depth d;
    if (acceptDepth.is_unreachable()) {
        d = acceptEodDepth;
    } else if (acceptEodDepth.is_unreachable()) {
        d = acceptDepth;
    } else {
        d = max(acceptDepth, acceptEodDepth);
    }

    if (d.is_unreachable()) {
        // If we're actually reachable, we'll have a min width, so we can
        // return infinity in this case.
        if (findMinWidth(h, filter, src).is_reachable()) {
            return depth::infinity();
        }
        return d;
    }

    // Invert sign and subtract one for start transition.
    assert(d.is_finite() && d > depth(0));
    return d - depth(1);
}