Find_Depth和Link的实现

在编译器的实现等应用中需要用到上述两类指令.

 

问题是 Find-Depth 指令如果不具路径压缩功能, 则执行 O(n) Find-Depth 指令,最坏情况下时间复杂度为 O(n2 ) ;但如果采用具有路径压缩功能 Find-Depth 指令,则原先树中在被压缩路径上的各结点深度会发生改变 ,如不采取其它措施,对其中某结点执行 Find-Depth 指令时,就会得到错误的深度信息。如果我们给每个结点增加一个字段记录其在原树中的深度,这样,虽可在 O(1) 时间完成一条 Find-Depth 指令,但在执行 Link 指令时,由于以 r 为根的子树中结点的深度全部发生了变化,我们势必要修改该子树中所有结点的深度字段。此工作量很大,最坏情况下, O(n) Link 指令的时间复杂度也为 O(n2 ) ;为了既能求得各点在原先树中的正确深度、又能使时间复杂度较小,我们需要使用具有路径压缩功能的 Find-Depth 指令 ;同时我们还需要采取一些辅助手段来保证深度计算的正确性。为此,我们对每个结点 v 增加 2 个字段( Count[v] Weight[v] ,并把经过改造的此类结点和树所构成的森林称为 D- 森林

 

一、问题说明


问题描述

编写能实现上述功能的Link(v,r) 指令程序,不要使用全局变量,设初始时两森林均由单结点树构成。上机依次执行:Link(2,1), Link(3,2), Link(5,4), Link(4,3), Link(7,6),Link(9,8), Link(8,7), Find-Depth(6), Link(6,5), Find-Depth(4), Find-Depth(7) 。 打印或抄写每条指令执行后各点的Weight 值,画出其时的两种森林。

二、程序功能说明 以程序演示


程序功能说明

find_depth(i) 主要是找到 D 森林根节点编号和 i 节点深度

link(v, r) 将以 r 链接到 v ,合并两棵树

程序演示结果

输入       dtree.link(2, 1);

       dtree.link(3, 2);

       dtree.link(5, 4);

       dtree.link(4, 3);

       dtree.link(7, 6);

       dtree.link(9, 8);

       dtree.link(8, 7);

dtree.find_depth(6)

dtree.find_depth(4)

dtree.find_depth(7)

输出结果:(注意下,这里的深度表示原森林的深度)

6 的深度: 3

weight[1]:1  weight[2]:7  weight[3]:-1  weight[4]:1  weight[5]:-3  weight[6]:3  weight[7]:2  weight[8]:1  weight[9]:-7 

4 的深度: 5

7 的深度: 2


深度

  深度                             权值

三、 算法设计

find_depth(i) 返回 D 森林根节点编号和 i 节点深度 ,它 的实现如下所示,要注意几点:

1.         如果是根节点 , 一个参数是 D 森林根节点编号,另一个为 weight 0

2.         i 的深度 =weight[i] + i 的父节点的 weight + i 的父节点的父节点的 weight+ ... + 一直到 D 森林根节点

3.         第一次 find 需要经过路径压缩 O(n) 次需要 O(n*G(n))

 

 

 

link(v, r) 将以 r 链接到 v ,合并两棵树, 的实现如下所示,但同样也要注意几点:

1.   首先要获得 D 森林 v 的根节点编号和 D 森林 r 的根节点编号以及 v 节点深度

2.   如果 count[rootOfV ] >= count[rootOfR] 则将 r 所在 D 森林中的根 rootOfR(r') 指向 v 所在 D 森林中的根 rootOfV(v')

3.   weight[rootOfR]- weight[rootOfR]+weight[rootOfV]=depth(v) +1

4.         如果 count[rootOfV ] < count[rootOfR] v’ 接到 r’

5.         需要修改两处地方: weight[rootOfR] - weight[rootOfR] = depth(v) + 1 和旧 weight[rootOfV] + weight[rootOfV] + weight[rootOfR] = depth[v]

 

 

 

四、实验结果分析

注意一下,在实现 find_depth 的时候使用到了 find find 实施带权路径压缩,我们这里使用递归的形式, O(n) 次指令的时间复杂度为 O(n*G(n))

对于实验结果,我们可以通过验证的方式来看是否正确, 6 4 7 的深度分别为 3 5 2 这是正确的,因为原树是以 9 为根,然后其他节点是链式连接的,如下图所示

对于权值我们可以这样验证,最后得出的 D 森林如下所示:(执行到 Link(6, 5) 时,当然如果继续往下执行的话,权值又会变化,因为路径会继续压缩)

比如说 6 节点,因为 6 节点在原森林的深度为 3 ,而从图中可以看出 6 的权值 +9 的权值 +2 的权值 =3+-7+7 = 3 因此,是正确的,同理,可以验证其他节点的情况。

五、“编”后感

算法侧重于时间和空间,该程序主要时间花费是在 find_depth link ,各自的时间复杂度都为 O(n*G(n)) ,另外就是验证程序,只需要验证程序的权值累加起来是否等于原森林的深度即可。要注意一点的是压缩后的权值和没有压缩后的权值是不一样的。

 

 

 

 

 

 

全部代码下载:http://download.csdn.net/source/2936858

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个简单的ROS程序,可以读取realsense深度相机的深度图像和rgb图像,并在rviz中分别显示。 ```cpp #include <ros/ros.h> #include <sensor_msgs/Image.h> #include <sensor_msgs/image_encodings.h> #include <cv_bridge/cv_bridge.h> #include <opencv2/highgui/highgui.hpp> // 定义全局变量,用于存储深度图像和RGB图像 cv::Mat depth_image; cv::Mat rgb_image; // 深度图像的回调函数 void depthCallback(const sensor_msgs::ImageConstPtr& msg) { // 将ROS消息转换为OpenCV图像 cv_bridge::CvImagePtr cv_ptr; try { cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::TYPE_32FC1); } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge exception: %s", e.what()); return; } // 保存深度图像 depth_image = cv_ptr->image; } // RGB图像的回调函数 void rgbCallback(const sensor_msgs::ImageConstPtr& msg) { // 将ROS消息转换为OpenCV图像 cv_bridge::CvImagePtr cv_ptr; try { cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8); } catch (cv_bridge::Exception& e) { ROS_ERROR("cv_bridge exception: %s", e.what()); return; } // 保存RGB图像 rgb_image = cv_ptr->image; } int main(int argc, char** argv) { // 初始化ROS节点 ros::init(argc, argv, "realsense_reader"); ros::NodeHandle nh; // 订阅深度图像和RGB图像的话题 ros::Subscriber depth_sub = nh.subscribe("/camera3/depth/image_raw", 1, depthCallback); ros::Subscriber rgb_sub = nh.subscribe("/camera3/rgb/image_raw", 1, rgbCallback); // 创建OpenCV窗口 cv::namedWindow("Depth Image"); cv::namedWindow("RGB Image"); // 循环读取深度图像和RGB图像,并在OpenCV窗口中显示 while (ros::ok()) { // 显示深度图像 if (!depth_image.empty()) { cv::imshow("Depth Image", depth_image); } // 显示RGB图像 if (!rgb_image.empty()) { cv::imshow("RGB Image", rgb_image); } // 等待按键,退出程序 char key = cv::waitKey(10); if (key == 27) // ESC键 { break; } // 处理ROS回调函数 ros::spinOnce(); } // 销毁OpenCV窗口 cv::destroyAllWindows(); return 0; } ``` 需要注意的是,该程序中使用了OpenCV库来显示深度图像和RGB图像,因此需要在CMakeLists.txt文件中添加OpenCV的依赖项。完整的CMakeLists.txt文件如下所示: ```cmake cmake_minimum_required(VERSION 2.8.3) project(realsense_reader) find_package(catkin REQUIRED COMPONENTS roscpp sensor_msgs cv_bridge image_transport ) find_package(OpenCV REQUIRED) catkin_package( CATKIN_DEPENDS roscpp sensor_msgs cv_bridge image_transport ) include_directories( ${catkin_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ) add_executable(${PROJECT_NAME} src/realsense_reader.cpp) target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ) install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) ``` 另外,需要在.launch文件中启动Gazebo仿真环境和realsense深度相机节点,并将/camera3/depth/image_raw和/camera3/rgb/image_raw话题分别映射到程序中定义的回调函数中。完整的.launch文件如下所示: ```xml <launch> <!-- 启动Gazebo仿真环境 --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="world_name" value="$(find realsense_gazebo)/worlds/realsense_world.world"/> </include> <!-- 启动realsense深度相机节点 --> <node name="realsense_node" pkg="realsense2_camera" type="realsense2_camera_node"> <param name="serial_no" value="123456789"/> <param name="enable_depth" value="true"/> <param name="enable_color" value="true"/> <param name="depth_height" value="480"/> <param name="depth_width" value="640"/> <param name="color_height" value="480"/> <param name="color_width" value="640"/> <param name="depth_fps" value="30"/> <param name="color_fps" value="30"/> </node> <!-- 映射/camera3/depth/image_raw话题 --> <node name="depth_image" pkg="image_transport" type="republish"> <remap from="/image_raw" to="/camera3/depth/image_raw"/> <remap from="/compressed" to="/camera3/depth/compressed"/> <remap from="/compressedDepth" to="/camera3/depth/compressedDepth"/> <remap from="/theora" to="/camera3/depth/theora"/> </node> <!-- 映射/camera3/rgb/image_raw话题 --> <node name="rgb_image" pkg="image_transport" type="republish"> <remap from="/image_raw" to="/camera3/rgb/image_raw"/> <remap from="/compressed" to="/camera3/rgb/compressed"/> <remap from="/compressedDepth" to="/camera3/rgb/compressedDepth"/> <remap from="/theora" to="/camera3/rgb/theora"/> </node> <!-- 启动realsense_reader节点 --> <node name="realsense_reader" pkg="realsense_reader" type="realsense_reader"/> </launch> ``` 启动.launch文件后,即可在rviz中看到深度图像和RGB图像的显示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值