当前位置: 首页 > 面试题库 >

切割图形集,Boost图形库

周培
2023-03-14
问题内容

我一直在努力寻找方法。我对快速找到图的割集感兴趣。我知道BGL支持在诸如edmonds_karp_max_flow支持的colorMap参数上通过迭代查找割集。Gomory
Hu算法需要多次调用最小切割算法。

我希望得到的结果是有一个包含以下内容的多图:(颜色,顶点)

以下代码是尝试从Boost
Graph库重写示例以将多图用于associative_property_map的尝试。可以使用以下命令完成代码的编译:clang
-lboost_graph -o edmonds_karp edmonds_karp.cpp或g ++而不是clang。我没有发现错误。

#include <boost/config.hpp>
#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/edmonds_karp_max_flow.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/read_dimacs.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/unordered_map.hpp>

int main()
{
  using namespace boost;

  typedef adjacency_list_traits < vecS, vecS, directedS > Traits;
  typedef adjacency_list < listS, vecS, directedS,
    property < vertex_name_t, std::string >,
    property < edge_capacity_t, long,
    property < edge_residual_capacity_t, long,
    property < edge_reverse_t, Traits::edge_descriptor > > > > Graph;

  Graph g;

  property_map < Graph, edge_capacity_t >::type
    capacity = get(edge_capacity, g);
  property_map < Graph, edge_reverse_t >::type rev = get(edge_reverse, g);
  property_map < Graph, edge_residual_capacity_t >::type
    residual_capacity = get(edge_residual_capacity, g);

  std::multimap<default_color_type, Traits::vertex_descriptor> colorMap;
  boost::associative_property_map< std::map<default_color_type,
                                            Traits::vertex_descriptor> >
      color_map(colorMap);

  Traits::vertex_descriptor s, t;
  read_dimacs_max_flow(g, capacity, rev, s, t);

  std::vector<Traits::edge_descriptor> pred(num_vertices(g));
  long flow = edmonds_karp_max_flow
      (g, s, t, capacity, residual_capacity, rev,
       make_iterator_property_map(color_map.begin()),
       &pred[0]);

  std::cout << "c  The total flow:" << std::endl;
  std::cout << "s " << flow << std::endl << std::endl;

  std::cout << "c flow values:" << std::endl;
  graph_traits < Graph >::vertex_iterator u_iter, u_end;
  graph_traits < Graph >::out_edge_iterator ei, e_end;
  for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
    for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
      if (capacity[*ei] > 0)
        std::cout << "f " << *u_iter << " " << target(*ei, g) << " "
          << (capacity[*ei] - residual_capacity[*ei]) << std::endl;

  // if using the original example, unedited, this piece of code works
  // BOOST_FOREACH(default_color_type x, color){
  //   std::cout << x << std::endl;
  // }

  return EXIT_SUCCESS;
}

提示将不胜感激。谢谢。


问题答案:

这是基于Boost BiMap的快速PoC

typedef boost::bimap<bimaps::list_of<default_color_type>, bimaps::set_of<Traits::vertex_descriptor> > smart_map;
smart_map colorMap;
boost::associative_property_map<smart_map::right_map> color_map(colorMap.right);

我从http://lpsolve.sourceforge.net/5.5/DIMACS_maxf.htm中提取了一个小样本,您可以看到它在
Live Coliru上显示
,输出:

c  The total flow:
s 15

c flow values:
f 0 1 5
f 0 2 10
f 1 3 5
f 1 4 0
f 2 3 5
f 2 4 5
f 3 5 10
f 4 5 5
ltr: 0 -> 5
ltr: 4 -> 0
ltr: 0 -> 1
ltr: 4 -> 2
ltr: 0 -> 3
ltr: 0 -> 4
rtl: 0 -> 4
rtl: 1 -> 0
rtl: 2 -> 4
rtl: 3 -> 0
rtl: 4 -> 0
rtl: 5 -> 0

完整清单:

#include <boost/foreach.hpp>
#include <boost/bimap.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/bimap/list_of.hpp>
#include <boost/bimap/set_of.hpp>
#include <boost/graph/edmonds_karp_max_flow.hpp>
#include <boost/graph/graph_utility.hpp>
#include <boost/graph/read_dimacs.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/unordered_map.hpp>

int main() {
    using namespace boost;

    typedef adjacency_list_traits<vecS, vecS, directedS> Traits;
    typedef adjacency_list<
        listS, vecS, directedS, property<vertex_name_t, std::string>,
        property<edge_capacity_t, long,
        property<edge_residual_capacity_t, long, 
        property<edge_reverse_t, Traits::edge_descriptor> > > > Graph;

    Graph g;

    property_map<Graph, edge_capacity_t>::type capacity                   = get(edge_capacity, g);
    property_map<Graph, edge_reverse_t>::type rev                         = get(edge_reverse, g);
    property_map<Graph, edge_residual_capacity_t>::type residual_capacity = get(edge_residual_capacity, g);

    typedef boost::bimap<bimaps::list_of<default_color_type>, bimaps::set_of<Traits::vertex_descriptor> > smart_map;
    smart_map colorMap;
    boost::associative_property_map<smart_map::right_map> color_map(colorMap.right);

    Traits::vertex_descriptor s, t;
    read_dimacs_max_flow(g, capacity, rev, s, t);

    std::vector<Traits::edge_descriptor> pred(num_vertices(g));
    long flow = edmonds_karp_max_flow(
            g, s, t, capacity, residual_capacity, rev,
            color_map, &pred[0]);

    std::cout << "c  The total flow:" << std::endl;
    std::cout << "s " << flow << std::endl << std::endl;

    std::cout << "c flow values:" << std::endl;
    graph_traits<Graph>::vertex_iterator u_iter, u_end;
    graph_traits<Graph>::out_edge_iterator ei, e_end;
    for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
        for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
            if (capacity[*ei] > 0)
                std::cout << "f " << *u_iter << " " << target(*ei, g) << " " << (capacity[*ei] - residual_capacity[*ei])
                          << std::endl;

    for (auto const& e : colorMap.left)  std::cout << "ltr: " << e.first << " -> " << e.second << "\n";
    for (auto const& e : colorMap.right) std::cout << "rtl: " << e.first << " -> " << e.second << "\n";

    return EXIT_SUCCESS;
}

更新

使用Boost MultiIndex创建双向映射:

struct VertexColor {
    Traits::vertex_descriptor vertex;
    boost::default_color_type color;
};

typedef boost::multi_index_container<
    VertexColor,
    bmi::indexed_by<
        bmi::hashed_non_unique<bmi::tag<struct by_color>,  bmi::member<VertexColor, boost::default_color_type, &VertexColor::color> >,
        bmi::ordered_unique   <bmi::tag<struct by_vertex>, bmi::member<VertexColor, Traits::vertex_descriptor, &VertexColor::vertex> >
    >
> smart_map;

现在,使用Boost Property Map建模
ReadWritePropertyMap

struct bidi_color_map {
    typedef smart_map::index<by_vertex>::type impl_t;
    bidi_color_map(impl_t& ref) : ref_(&ref) {}
    impl_t       &get()       { return *ref_; }
    impl_t const &get() const { return *ref_; }
private:
    impl_t* ref_;
};

namespace boost { 
    template <> struct property_traits<bidi_color_map> {
        typedef default_color_type          value_type;
        typedef default_color_type          reference;
        typedef Traits::vertex_descriptor   key_type;
        typedef read_write_property_map_tag category;
    };
}

boost::property_traits<bidi_color_map>::reference get(bidi_color_map const& idx, boost::property_traits<bidi_color_map>::key_type const& key) {
    auto it = idx.get().find(key);
    if (it != idx.get().end())
        return it->color;
    else
        throw std::range_error("key not found in index");
}

void put(bidi_color_map& idx, boost::property_traits<bidi_color_map>::key_type const& key, boost::property_traits<bidi_color_map>::value_type val) {
    auto it = idx.get().find(key);
    if (it != idx.get().end())
        idx.get().modify(it, [val](VertexColor& p) { p.color = val; });
    else
        idx.get().insert({key,val});
}

现在,您可以将其作为颜色图传递:

    smart_map colorMap;
    bidi_color_map color_map(colorMap.get<by_vertex>());

看到它 住在Coliru 以及



 类似资料:
  • 问题可能涉及:使用boost图形库:如何通过从文件中读取边缘列表来创建图形 然而,这个答案并没有真正帮助我。 我想使用Boost的邻接列表类创建一个图。数据在一个有两列的。txt文件中。 理想的情况是,我想这样做: 类似于:www.boost.org/doc/libs/1_56_0/libs/graph/example/undirected_marcincy_list.cpp 但是,我得到一个编译

  • 问题内容: 如何使用Java 剪切文件? 我想要的是: 当用户按下标有按钮的按钮时,应将音频从前一个(以纳秒为单位)剪切到当前位置(以纳秒为单位)。 (在剪切声音后,标记被定位到当前位置(以纳秒为单位)) 当我获得一段音频后,我想保存该段音频文件。 我怎样才能做到这一点 ? 问题答案: 最初由Martin Dow回答 }

  • 图形概述 理解图形系统是深入游戏开发的关键。本章详细介绍 Unity 的图形特性,例如光照和渲染。

  • 图形 Unity 提供了惊人的视觉保真度、渲染力和临场感。 Unity 为你的游戏提供符合直觉的实时全局光照和基于物理的着色器。从白天,到晚上霓虹灯的绚丽辉光;从光晕,到昏暗的午夜街道和阴暗的隧道 — 支持在任意平台上创建令人着迷和回味无穷的游戏。 本章将介绍光照、摄像机、材质、着色、纹理、粒子效果和视觉效果等内容。 另外,请参阅 图形知识库。 在教程部分还有许多有用的图形教程。 相关教程:图形

  • 在你的文件中最常见的图层应该就是图形了。Sketch 提供了多种不同的基本图形供你选择:圆形,矩形,星型等等。这几个图形中会有几个有趣的额外选项,比如星型和圆角矩形。 你只需单击工具栏中的 添加(Insert)>图形(Shape) 按钮,选择一个图形,便可以开始创作。当你的鼠标在画布上拖拽的时候,Sketch 会提示你这个图形的大小,松开鼠标,便会成功添加图形,右边的检查器上也会立即显示出这个图形

  • 本篇教程从一些基础开始,描述了如何使用 LCUI 提供的图形 API 来绘制 2D 图形。教程中提供的例子,会让你明白可以用图形 API 做什么,也会提供一些代码片段来帮助你开始构建自己的内容。 图形对象 图形对象是一个记录了位图的像素数据和宽高等信息的对象,在 LCUI 中它被定义为 LCUI_Graph 结构体类型,与之相关的函数都以 Graph_ 前缀命名。为了书写方便,在下文中我们将用“图

  • 图形工具 常见图形工具: Two.js Fabric.js 画布: Paper.js EaselJS SVG: svg.js Snap.svg Raphaël d3 Webgl: three.js pixi.js