我尝试将boost::lengauer_tarjan_dominator_tree与custom vertex properties的图表一起使用,但无法编译一个简单的示例:
#include <vector>
#include <iterator>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/dominator_tree.hpp>
#include <boost/property_map/property_map.hpp>
struct GraphNode
{
explicit GraphNode(unsigned i) : index {i} {}
unsigned index;
};
using Graph = boost::adjacency_list<boost::listS, boost::listS,
boost::bidirectionalS, GraphNode, boost::no_property>;
using Vertex = boost::graph_traits<Graph>::vertex_descriptor;
int main()
{
Graph g {};
const auto u = boost::add_vertex(GraphNode {0}, g);
const auto v = boost::add_vertex(GraphNode {1}, g);
const auto x = boost::add_vertex(GraphNode {2}, g);
const auto y = boost::add_vertex(GraphNode {3}, g);
const auto z = boost::add_vertex(GraphNode {4}, g);
boost::add_edge(u, v, g);
boost::add_edge(u, x, g);
boost::add_edge(v, y, g);
boost::add_edge(x, y, g);
boost::add_edge(y, z, g);
const auto index_map = boost::get(&GraphNode::index, g);
std::vector<Vertex> dom_tree_pred_vector(boost::num_vertices(g),
boost::graph_traits<Graph>::null_vertex());
auto dom_tree_pred_map = boost::make_iterator_property_map(std::begin(dom_tree_pred_vector),
index_map);
boost::lengauer_tarjan_dominator_tree(g, u, dom_tree_pred_map);
}
我试图从文档中给出的example进行调整。
以下是错误消息的一部分:
/usr/local/include/boost/graph/detail/adjacency_list.hpp:2544:33: error: cannot form a reference to 'void'
typedef const value_type& const_reference;
^
/usr/local/include/boost/graph/dominator_tree.hpp:355:31: error: no matching function for call to 'get'
const IndexMap indexMap = get(vertex_index, g);
我还尝试使用方法的第二种形式明确传递索引映射,但没有成功。我注意到这个方法界面似乎与其他图形方法略有不同,例如depth_first_search,其中vertex_index_map
是一个命名参数。
是否可以将此方法用于自定义顶点属性?
答案 0 :(得分:2)
问题 - 一如既往 - 是使用<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/value_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delete"/>
</LinearLayout>
以外的东西作为顶点容器。您丢失了内置import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<String> items = new ArrayList<>(
Arrays.asList("first", "second", "third"));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView myRecyclerView = (RecyclerView)
findViewById(R.id.my_recycler_view);
myRecyclerView.setAdapter(new MyAdapter());
}
private class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(MainActivity.this)
.inflate(R.layout.my_item, parent, false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return items.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView valueTextView;
private Button deleteButton;
public MyViewHolder(View itemView) {
super(itemView);
valueTextView = (TextView) itemView.findViewById(R.id.value_text);
deleteButton = (Button) itemView.findViewById(R.id.delete_button);
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = (int) v.getTag();
items.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, items.size());
}
});
}
public void bind(int position) {
valueTextView.setText(items.get(position));
deleteButton.setTag(position);
}
}
}
}
属性,因此必须将其提供给API。
vecS
正确地尝试了,但在内部算法仍然会查找vertex_index
标记属性。
我能看到这项工作的唯一两种方式是,
手动执行DFS阶段(因为即使index_map
的全参数重载也无法将正确的索引映射转发到DFS中)。然后,您可以调用vertex_index_t
实现并获得结果。
或者您可以告诉图书馆您的图表的索引图。
(最后,你可以接受命运并使用lengauer_tarjan*
作为顶点容器选择器。我怀疑这显然不是你想要的。)
使用第二种方法,这可能是最优雅的。以下是要添加的特化/重载:
lengauer_tarjan_dominator_tree_without_dfs
<强> Live On Coliru 强>
vecS
打印
namespace boost {
template <>
struct property_map<Graph, vertex_index_t> {
typedef typename property_map<Graph, size_t GraphNode::*>::type type;
typedef typename property_map<Graph, size_t GraphNode::*>::const_type const_type;
};
static auto get(vertex_index_t, Graph& g) { return get(&GraphNode::index, g); }
static auto get(vertex_index_t, Graph const& g) { return get(&GraphNode::index, g); }
}