精确覆盖问题学习笔记(五)——优化算法的实现代码

本文介绍了一种基于 Dancing Links 的精确覆盖问题求解算法,并详细展示了其数据结构设计及核心算法流程,包括创建链表、覆盖与还原操作以及搜索过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//文件node.h
#pragma once

struct CNode
{
	CNode* Left;      //左节点指针
	CNode* Right;     //右节点指针

	CNode* Up;        //上节点指针,对列节点,则为本列最后一个元素的指针
	CNode* Down;      //下节点指针,对列节点,则为本列第一个元素的指针
	
	int name;			//对普通节点,为所在子集的编号,即行号;
						//对列节点,为列编号
};

struct CColumnHead:public CNode
{
	int size;   //本列元素的个数
};



struct CGrid:public CNode
{
	CColumnHead* columnHead;   //列头节点的指针

};
//文件ExactCover.h
#pragma once
#include <vector>
#include <set>
#include <iostream>
#include <fstream>
using namespace std;
#include "node.h"

class CExactCover
{
public:
	CExactCover(const vector<vector <int> >& matrix); //从矩阵中读入数据,建立链表
	~CExactCover(void);

private:
	const CColumnHead* getColumn(int name)const;
	const CColumnHead* selectColumn()const;        //选择含1个数最少的列      
	void cover(const CColumnHead *c);        //将某一列及其相关的节点从矩阵中删除
	void uncover(const CColumnHead *c);      //将某一列及其相关的节点重新加入到矩阵中
	void CreateHead(const vector<vector <int> >& matrix); //建立头节点链表
	void CreateRows(const vector<vector <int> >& matrix);  //建立数据节点

	bool search();   //求解算法
	void print(const vector<vector <int> >& matrix,ostream &os) const; //输出可行解private:set<int>m_solution; //解集
	CColumnHead* m_master; //列头链表的头节点
};
//文件ExactCover.cpp
#include <iomanip>
#include <sstream>
#include <map>
using namespace std;
#include "ExactCover.h"
void CExactCover::CreateHead( const vector<vector <int> >& matrix )
{
	m_master = new CColumnHead;
	m_master->size = 0;
	m_master->Left  = m_master;
	m_master->Right = m_master;

	CColumnHead* prev = m_master;

	const int elementNum = matrix[0].size();
	for (int i = 0
		; i < elementNum
		;++i
		)
	{
		CColumnHead* c=new CColumnHead;
		c->name = i+1;
		c->size = 0;
		
		prev->Right = c;
		c->Left = prev;

		c->Right = m_master;
		m_master->Left = c;

		c->Up = c;
		c->Down = c;

		prev = c;
		++m_master->size;
	}
}

void CExactCover::CreateRows( const vector<vector <int> >& matrix )
{
	const int subsetNum=matrix.size();
	const int elementNum = matrix[0].size();
	
	for (int i=0;i<subsetNum;++i)
	{
		CGrid* head=NULL;
		CGrid* prev=NULL;
		int num=0;
		for(int j=0;j<elementNum;++j)
		{
			if (matrix[i][j]==1)
			{
				++num;

				CGrid* cell=new CGrid;
				cell->name=i;
				
				CColumnHead* c=const_cast<CColumnHead*>(getColumn(j+1));
				CGrid* lastCell = static_cast<CGrid*>(c->Up);
				
				lastCell->Down = cell;
				cell->Up= lastCell;

				c->Up = cell;
				cell->Down = c;
				cell->columnHead = c;

				++c->size;
				
				if (num==1)
				{
					head = cell;
					prev = head;
				}
				
				cell->Left =  prev;
				cell->Right = head;
					
				head->Left = cell;
				prev->Right = cell;
				
				prev = cell;
			}
		}
	}
}




CExactCover::CExactCover(const vector<vector <int> >& matrix)
{
	CreateHead(matrix);
	CreateRows(matrix);

}



CExactCover::~CExactCover(void)
{

}
void CExactCover::cover(const CColumnHead *c )
{
	//将第c列从列标题中删除
	c->Right->Left = c->Left;
	c->Left->Right = c->Right;
	m_master->size--;
	

	//依次处理和所有和本列相关的行
	for (CNode* columnNode = c->Down
		;columnNode != static_cast<const CNode*> (c)
		;columnNode = columnNode->Down
		)
	{

		//依次向右遍历本行的除第c列以外的的每个节点
		for (CGrid* rowNode=static_cast<CGrid*>(columnNode->Right)
			;rowNode!=columnNode
			;rowNode=static_cast<CGrid*>(rowNode->Right)
			)
		{

			//将本行的当前节点从所在列中摘除
			rowNode->Up->Down = rowNode->Down;
			rowNode->Down->Up = rowNode->Up; 
			
			rowNode->columnHead->size--;     //摘除完毕之后所在列的元素个数减1
		}
	}
}

void CExactCover::uncover(const CColumnHead *c){


	//将本列的各相关行加入到矩阵中
	for (CNode* columnNode=c->Up
		;columnNode != c
		;columnNode = columnNode->Up
		)
	{
		for (CGrid* rowNode=static_cast<CGrid*>(columnNode->Right)
			;rowNode!=columnNode
			;rowNode=static_cast<CGrid*>(rowNode->Right)
			)
		{
			//将本行的当前节点加回到原来的列中
			rowNode->Up->Down = rowNode;
			rowNode->Down->Up = rowNode; 

			rowNode->columnHead->size++;     //恢复完毕之后所在列的元素个数加1
		}
	}
	
	//把c列重新到加入列标题中
	c->Left->Right=const_cast<CColumnHead*>(c);
	c->Right->Left=const_cast<CColumnHead*>(c);  
	m_master->size++;
}

bool CExactCover::search(int k)
{
	bool flag = false;

	//矩阵为空时问题已经解决,返回true
	if (m_master->Right==m_master)
		flag =true;
	else
	{
		cover(c);
		
		for ( CGrid* row=static_cast<CGrid*>(c->Down)
			; static_cast<CNode*>(row)!= static_cast<CNode*>(const_cast<CColumnHead*>(c))
			;row=static_cast<CGrid*>(row->Down),++sublevel
			)
		{
			for(CGrid* cell=static_cast<CGrid*>(row->Right)
				;cell!=row
				;cell=static_cast<CGrid*>(cell->Right)
				)
			{
				cover(cell->columnHead);
			}

			flag =search(k+1);

			if (flag)
			{
				m_solution.insert(row->name);
				flag = true;
				break;
			}
			else
			{
				for ( CGrid* cell=static_cast<CGrid*>(row->Left)
					; cell!=row
					; cell=static_cast<CGrid*>(cell->Left)
					)
				{
					uncover(cell->columnHead);
				}
			}


		}
		if (!flag)
			uncover(c);
	}
	return flag;
}

const CColumnHead* CExactCover::selectColumn() const
{
	CColumnHead *min=static_cast<CColumnHead*>(m_master->Right);
	
	for (CColumnHead *c=min
		;c!=m_master
		;c=static_cast<CColumnHead*>(c->Right)
		)
	{
		if (c->size<min->size)
			min=c;
	}
	return min;
}

void CExactCover::print
	 (const vector<vector <int> >& matrix
	  ,ostream& os/*=log*/ 
	 )const
{
	const int elementNum = matrix[0].size();
	for(set<int>::const_iterator it = m_solution.begin()
		;it != m_solution.end() 
		;++it
		)
	{
                os << (char)('A'+*it)<<"={";
		int i=*it;
		for(int j=0;j<elementNum;++j)
			os << matrix[i][j] << ' ';
		os << "}"<<endl;
	}
}

const CColumnHead* CExactCover::getColumn( int name ) const
{
	CColumnHead* c=static_cast<CColumnHead*>(m_master->Right);
	for ( 
		; c!= m_master
		; c=static_cast<CColumnHead*>(c->Right)
		)
	{
		if (c->name==name)
			break;
	}

	return c;
}
//文件main.cpp
#include "ExactCover.h"
const int ELEMENT_NUM=7 ; //元素的个数
const int SUBSET_NUM=6;   //子集的个数

const int U[ELEMENT_NUM]={1,2,3,4,5,6,7};  //全集
const char NAMES[SUBSET_NUM]={'A','B','C','D','E','F'};  //各子集的名字
//0-1矩阵
const int Matrix[SUBSET_NUM][ELEMENT_NUM]={
	 {1,0,0,1,0,0,1}
	,{1,0,0,1,0,0,0}
	,{0,0,0,1,1,0,1}
	,{0,0,1,0,1,1,0}
	,{0,1,1,0,0,1,1}
	,{0,1,0,0,0,0,1}
};

int main(int argc,char* argv[])
{
	vector<vector <int> > M(SUBSET_NUM, vector<int>(ELEMENT_NUM));
	for(int i=0;i<SUBSET_NUM;++i)
		for(int j=0;j<ELEMENT_NUM;++j)
			M[i][j] = Matrix[i][j];

	CExactCover s(M);

	if (s.search())
		s.print(M,cout);

	system("pause");

	return 0;
}


运行结果:

B={1 0 0 1 0 0 0 }
D={0 0 1 0 1 1 0 }
F={0 1 0 0 0 0 1 }

### 2D Gaussian Splatting 的概念 2D Gaussian Splatting 是一种用于高效表示和渲染三维场景的技术,其核心思想是通过二维高斯分布(2D Gaussians)来近似三维空间中的物体表面[^2]。相比传统的基于体素或网格的方法,2DGS 提供了一种更加紧凑且快速的方式来进行场景建模和渲染。 --- ### 2D Gaussian Splatting 的实现方法 #### 数据结构设计 2D Gaussian Splatting 使用的是 **定向椭圆盘** 来作为基本单元,这些单元可以看作是对三维场景的一种简化表示形式。每一个 2D 高斯分布由以下几个参数定义: - 中心位置 $(\mu_x, \mu_y)$ 表示该高斯分布在图像平面上的位置。 - 协方差矩阵 $\Sigma$ 描述了形状和方向的信息。 - 不透明度 ($\alpha$) 控制可见程度。 - RGB颜色值决定视觉效果。 这种数据结构的设计使得它能够很好地适应现代图形处理硬件的能力,在GPU上执行高效的并行运算成为可能[^4]。 #### 渲染过程优化 在实际渲染过程中,2DGS 利用了精确的光线与椭圆形基元之间的相交测试技术 ("ray-splat intersection") ,从而实现了比传统体积渲染更高的精度以及更低的时间复杂度。具体来说: 1. 对于每一条从相机出发到达屏幕像素点的视线(ray),找到与其发生碰撞的所有splat; 2. 计算每个被击中的splat对该特定像素贡献的颜色强度; 3. 将所有相关联的结果按照一定规则融合起来形成最终画面输出。 这种方法避免了由于视角变化而导致的传统3D GS可能出现的问题——即当观察角度改变时产生的深度排序不连贯现象。 --- ### 应用场景分析 #### 新视图合成 得益于其强大的表达能力和优秀的性能表现,2D Gaussian Splatting 特别适合应用于虚拟现实(VR)/增强现实(AR)领域内的实时动态环境创建任务之中。例如,在电影制作或者游戏开发当中,可以通过采集少量真实世界的图片资料之后构建完整的沉浸式体验场所。 #### 自动驾驶感知系统改进 另外一方面,在自动驾驶汽车所依赖的各种传感器获取的数据基础上运用此算法还可以进一步提升对于周围障碍物识别的速度与准确性。因为相较于其他类型的模型而言,采用2D GS方式不仅可以减少存储需求量还能加快推理速度,这对于需要即时响应的安全关键型应用尤为重要[^3]。 #### SLAM 系统升级 同时,在同步定位与地图绘制(SLAM)研究方面也有着广泛的应用前景。借助于2D Gaussian Splatting 技术的优势特性可以帮助机器人更有效地理解其所处的空间布局情况,并据此做出合理的行为决策。 ```python import numpy as np def render_2d_gaussian(center, covariance_matrix, alpha, color): """ Simulates rendering a single 2D Gaussian splat. Parameters: center (tuple): The mean position of the Gaussian distribution on image plane. covariance_matrix (np.ndarray): Covariance matrix defining shape and orientation. alpha (float): Opacity value controlling visibility level. color (list or tuple): RGB values specifying appearance characteristics. Returns: rendered_image (np.ndarray): A synthetic representation showing how this element contributes visually within scene context. """ # Placeholder implementation details omitted here... pass ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值