进程同步及避免死锁经典问题

Linux多进程实现读写者问题:读优先、写优先、公平排队实现 1. 任务简介 一个数据文件或记录可被多个进程共享,我们把只要求读该文件的进程称为 reader进稈,其他进程称为writer进程。允许多个进程同时读一个共享对象,因为读操作不会使数据文件混乱。但不允许一个writer进程和其他reader进程或writer进程同时访回共享对象,因为这种访问将会引起混乱。所谓读者-写者问题(reader-writer problem)是指保证一个writer进程必须与其他进程互斥地访问共享对象的向步问题。读者-写者问题常被用手测试新同步原语。 读者-写者问题被提出后,就一直 阅读详情

定义PV操作的含义:PV操作是由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:
    P(S):将信号量S的值减1,即S=S-1;如果S>0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。
    V(S):将信号量S的值加1,即S=S+1;如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。
P操作相当于申请资源,而V操作相当于释放资源。


一、读者-写者问题

计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader),另一些进程则要求修改数据(称为写者Writer)。就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:

(1)允许多个读者同时执行读操作;
(2)不允许读者、写者同时操作;
(3)不允许多个写者同时操作。
Reader和Writer的同步问题分为读者优先、弱写者优先(公平竞争)和强写者优先三种情况,它们的处理方式不同:

1、读者优先

int rc = 0; //记录有多少个读者在读
semaphore rc_semaphore = 1; //对rc互斥访问的信号量
semaphore write_semaphore = 1; //保证读写互斥的信号量

void reader()
{
	do 
	{
		P(rc_semaphore);
		rc++;
		if(1==rc)
			P(write_semaphore);
		V(rc_semaphore);

		read operating.....

	    P(rc_semaphore);
		rc--;
		if(0==rc)
			V(write_semaphore);
		v(rc_semaphore);
	} while (true);
}

void writer()
{
	do 
	{
		P(write_semaphore);
		write operating.....
		V(write_semaphore);
	} while (true);
}
缺点:当不断有读者来读取时,写者就会陷入无限的等待。

2、写者优先(弱优先性)

int rc = 0; //记录有多少个读者在读
semaphore rc_semaphore = 1; //对rc互斥访问的信号量
semaphore write_semaphore = 1; //保证读写互斥的信号量
semaphore read_semaphore = 1;

void reader()
{
	do 
	{
		P(read_semaphore);
		P(rc_semaphore);
		rc++;
		if(1==rc)
			P(write_semaphore);
		V(rc_semaphore);
		V(read_semaphore);

		Reading the file....

		P(rc_semaphore);
		rc--;
		if(0==rc)
			V(write_semaphore);
		V(rc_semaphore);

	} while (true);
}

void writer()
{
	do 
	{
		P(read_semaphore);
		P(write_semaphore);
		writing the file.....
		V(write_semaphore);
		V(read_semaphore);
	} while (true);
}
缺点:这个是按照先来先服务的原则进行读写的,比如当一个进程在写时,来了N个进程读,读者们都在等写者结束,此时又来了个写者,第二个写者就要等前面N个读者读完后才能写。

3、写者优先(强优先性)

int rc = 0;
int wc = 0;
semaphore write_semaphore = 1;
semaphore rc_semaphore =1;
semaphore wc_semaphore = 1;

void reader()
{
	do 
	{
		P(read_semaphore);
		P(rc_semaphore);
		rc++;
		if(1==rc)
			P(write_semaphore);
		V(rc_semaphore);
		V(read_semaphore);

		reading the file.....

		P(rc_semaphore);
		rc--;
		if(0==rc)
			V(write_semaphore);
		V(rc_semaphore);
	} while (true);
}

void writer()
{
	do 
	{
		P(wc_semaphore);
		wc++;
		if(1==wc)
			P(read_semaphore);
		V(wc_semaphore);

		P(write_semaphore);
		writing the file......
		V(write_semaphore);

		P(wc_semaphore);
		wc--;
		if(0==wc)
			V(read_semaphore);
		V(wc_semaphore);
	} while (true);
}

保证了写者优先,只要有写者在写,后来的读者写者中优先执行写者。

二、生产者-消费者

生产者-消费者问题指的是在若干个生产者生产产品,放入共享的缓冲区,若干消费者从缓冲区中取出产品消费;生产者和消费者是互斥访问共享的缓冲区的,若缓冲区没有空位生产者要等待,若缓冲区没有产品消费者要等待,以下通过代码来演示这个过程。

注:以下代码修改自http://blog.sina.com.cn/s/blog_58069bd20100as5w.html

#include <windows.h>
#include <iostream>

using namespace std;

const unsigned short SIZE_OF_BUFFER = 10; //缓冲区长度
unsigned short ProductID = 0; //产品号
unsigned short ConsumeID = 0; //将被消耗的产品号
unsigned short in = 0; //产品进缓冲区时的缓冲区下标
unsigned short out = 0; //产品出缓冲区时的缓冲区下标
int g_buffer[SIZE_OF_BUFFER]; //缓冲区是个循环队列

HANDLE g_hMutex; //用于线程间的互斥
HANDLE g_hFullSemaphore; //当缓冲区满时迫使生产者等待
HANDLE g_hEmptySemaphore; //当缓冲区空时迫使消费者等待
DWORD WINAPI Producer(LPVOID); //生产者线程
DWORD WINAPI Consumer(LPVOID); //消费者线程

int main()
{
	//创建各个互斥信号
	g_hMutex = CreateMutex(NULL,FALSE,NULL);
	g_hFullSemaphore = CreateSemaphore(NULL,0,SIZE_OF_BUFFER,NULL);
	g_hEmptySemaphore = CreateSemaphore(NULL,SIZE_OF_BUFFER,SIZE_OF_BUFFER,NULL);
	
	//调整下面的数值,可以发现,当生产者个数多于消费者个数时,
	//生产速度快,生产者经常等待消费者;反之,消费者经常等待
	const unsigned short PRODUCERS_COUNT = 3; //生产者的个数
	const unsigned short CONSUMERS_COUNT = 2; //消费者的个数
	//总的线程数
	const unsigned short THREADS_COUNT = PRODUCERS_COUNT+CONSUMERS_COUNT;
	HANDLE hThreads[THREADS_COUNT]; //各线程的handle
	DWORD producerID[PRODUCERS_COUNT]={1,2,3}; //生产者线程的标识符
	DWORD consumerID[CONSUMERS_COUNT]={1,2}; //消费者线程的标识符
	//创建生产者线程
	for (int i=0;i<PRODUCERS_COUNT;++i){
		hThreads[i]=CreateThread(NULL,0,Producer,&producerID[i],0,NULL);
		if (hThreads[i]==NULL) return -1;
	}
	//创建消费者线程
	for (int i=0;i<CONSUMERS_COUNT;++i){
		hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,&consumerID[i],0,NULL);
		if (hThreads[i]==NULL) return -1;
	}

	while(true){
		Sleep(10000);
	}

	return 0;
}
//生产一个产品。简单模拟了一下,仅输出新产品的ID号
void Produce()
{
	std::cerr << "Producing " << ++ProductID << " ... ";
	std::cerr << "Succeed" << std::endl;
}
//把新生产的产品放入缓冲区
void Append()
{
	std::cerr << "Appending a product ... ";
	g_buffer[in] = ProductID;
	in = (in+1)%SIZE_OF_BUFFER;
	std::cerr << "Succeed" << std::endl;
	//输出缓冲区当前的状态
	for (int i=0;i<SIZE_OF_BUFFER;++i){
		std::cout << i <<": " << g_buffer[i];
		if (i==in) std::cout << " <-- 生产";
		if (i==out) std::cout << " <-- 消费";
		std::cout << std::endl;
	}
}
//从缓冲区中取出一个产品
void Take()
{
	std::cerr << "Taking a product ... ";
	ConsumeID = g_buffer[out];
	g_buffer[out] = 0;
	out = (out+1)%SIZE_OF_BUFFER;
	std::cerr << "Succeed" << std::endl;
	//输出缓冲区当前的状态
	for (int i=0;i<SIZE_OF_BUFFER;++i){
		std::cout << i <<": " << g_buffer[i];
		if (i==in) std::cout << " <-- 生产";
		if (i==out) std::cout << " <-- 消费";
		std::cout << std::endl;
	}
}
//消耗一个产品
void Consume()
{
	std::cerr << "Consuming " << ConsumeID << " ... ";
	std::cerr << "Succeed" << std::endl;
}
//生产者
DWORD WINAPI Producer(LPVOID lpPara)
{
	while(true){
		WaitForSingleObject(g_hEmptySemaphore,INFINITE);
		WaitForSingleObject(g_hMutex,INFINITE);
		Produce();
		Append();
		Sleep(3000);
		ReleaseMutex(g_hMutex);
		ReleaseSemaphore(g_hFullSemaphore,1,NULL);
	}
	return 0;
}
//消费者
DWORD WINAPI Consumer(LPVOID lpPara)
{
	while(true){
		WaitForSingleObject(g_hFullSemaphore,INFINITE);
		WaitForSingleObject(g_hMutex,INFINITE);
		Take();
		Consume();
		Sleep(3000);
		ReleaseMutex(g_hMutex);
		ReleaseSemaphore(g_hEmptySemaphore,1,NULL);
	}
	return 0;
}

三、哲学家进餐

问题描述:

五个哲学家围坐在一张圆桌周围,每个哲学家面前都有一盘通心粉。由于通心粉很滑,所以需要两把叉子才能夹住。相邻两个盘子之间放有一把叉子,哲学家的生活中有两种交替活动时段:即吃饭和思考。当一个哲学家觉得饿了时,他就试图分两次去取其左边和右边的叉子,每次拿一把,但不分次序。如果成功地得到了两把叉子,就开始吃饭,吃完后放下叉子继续思考。关键问题是:能为每一个哲学家写一段描述其行为的程序,且决不会死锁吗(最好能达到最大的并行程度)?

解法思路:

1、为每个哲学家分配一个semaphore[i]初始值为0,最大值为1

2、当一个哲学家试图进餐时先通过互斥量获得对哲学家们的状态state的独占性访问         

3、改变i哲学家的状态为HUNGRY,测试其左右哲学家是否在用餐,若左右哲学家都不在用餐,则i哲学家可以用餐,改变state[i]=EATING,释放其semaphore[i],释放state,拿起餐插成功进餐;若左右哲学家有人在进餐,释放state,i哲学家等待

4、哲学家用餐完毕,获取对state的独占性访问,改变state[i]=THINKING,此时i哲学家释放了两个餐插,测试其左右哲学家是否在HUNGRY状态

5、重复2-4步骤直到达到最大进餐次数


参考如下代码:(以下代码修改自http://blog.163.com/diaoshuo_1/blog/static/318902012009418115121514/)

/*
Item       The Dining Philosophers Problem
具体要求
1) 5个哲学家,先吃饭,后思考。
2) 每个哲学家都需要吃9顿饭,思考9次,然后结束。
3)吃饭时间为3~7秒的随机时间
4)思考时间为3~9秒的随机时间
*/
#include <windows.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#define N       5            //哲学家数目
#define MAXNUM 9     //进餐思考次数
#define LEFT (i+N-1)%N            //i为左邻居编号
#define RIGHT      (i+N+1)%N           //i为右邻居编号
#define THINKING       0                          //哲学家在思考
#define HUNGRY  1                                 //哲学家视图拿起叉子
#define EATING    2                                 //哲学家进餐

///////线程参数
typedef struct _THREAD_ARGS{
	int id;//哲学家编号
	int maxnum; //进餐思考最大次数
}THREAD_ARGS, *PTHREAD_ARGS;

int state[N];//用来记录每位哲学家的状态
int g_philobuf_fork_num;//缓冲区中叉子数目
char mutex_g_buf[]="PS_IPC_PHILO_G_BUF";
HANDLE mutex_g_buf_h;  //为了互斥访问state[N]
//Semaphores' Name
char* sem_perphilo_name[N] = {"PS_IPC_PHILO_SEM_PERPHILO_0","PS_IPC_PHILO_SEM_PERPHILO_1",
"PS_IPC_PHILO_SEM_PERPHILO_2","PS_IPC_PHILO_SEM_PERPHILO_3",
"PS_IPC_PHILO_SEM_PERPHILO_4"};

HANDLE sem_perphilo_h[N];   //每个哲学家一个semaphore,初始值为0,最大值为1

DWORD WINAPI philosopher(void *pArgs);
void take_forks(int i);
void put_forks(int i);
void test(int i);

//线程函数
DWORD WINAPI philosopher(void *pArgs)
{
	PTHREAD_ARGS pTHREAD_ARGS;
	pTHREAD_ARGS=(PTHREAD_ARGS)pArgs;
	int i=pTHREAD_ARGS->id;
	int totalNum = pTHREAD_ARGS->maxnum;

	for(int count=0;count<totalNum;count++)
	{
		take_forks(i);
		srand ((DWORD)time(NULL));
		int eat_t=rand()%4000 + 3000;
		Sleep(eat_t);
		printf("Philosopher %d finishes eating!this is the %d(th) eating time! eat_t:%d\n",i,count+1,eat_t);
		put_forks(i);

		srand ((DWORD)time(NULL));
		int think_t= rand()%6000 + 3000;
		Sleep(think_t);
		printf("Philosopher %d finishes thinking!this is the %d(th) thinking time! think_t:%d\n",i,count+1,think_t);
	}

	printf("Philosopher %d has finished all the eating and thinking activity\n!",i);

	return 0;
}

void take_forks(int i)
{
	WaitForSingleObject(mutex_g_buf_h,INFINITE);
	state[i]=HUNGRY;
	printf("*************************take_forks start***************************\n");
	printf("Philosopher %d is hungry!  Try to take the forks\n",i);
	printf("*************************take_forks end***************************\n\n");
	test(i);
	ReleaseMutex(mutex_g_buf_h);

	WaitForSingleObject(sem_perphilo_h[i],INFINITE);
}

void put_forks(int i)
{
	WaitForSingleObject(mutex_g_buf_h,INFINITE);
	state[i]=THINKING;
	g_philobuf_fork_num=g_philobuf_fork_num-2;//放下了两把叉子
	printf("*************************put_forks start***************************\n");
	printf("Philosopher %d puts down the fork and starts thinking! current forks num:%d\n",i,g_philobuf_fork_num);
	printf("*************************put_forks end***************************\n\n");
	test(LEFT);
	test(RIGHT);
	ReleaseMutex(mutex_g_buf_h);
}
void test(int i)
{
	LONG oldSemValue;
	if(state[i]==HUNGRY&&state[LEFT]!=EATING&&state[RIGHT]!=EATING)
	{
		state[i]=EATING;
		g_philobuf_fork_num=g_philobuf_fork_num+2;//拿起了两把叉子
		printf("*************************test start***************************\n");	
		printf("After testing,Philosopher %d can starts eating! current forks num:%d\n",i,g_philobuf_fork_num);
		printf("*************************test end***************************\n\n");
		ReleaseSemaphore(sem_perphilo_h[i],1,&oldSemValue);
	}
}

int main(int argc,char*argv[])
{
	time_t launch=time(NULL);

	printf("****************************************************\n");
	printf("开始运行时间:%s",ctime(&launch));
	printf("哲学家就餐问题\n");
	printf("哲学家数量:%d\n",N);
	printf("进餐思考次数:%d\n",MAXNUM);      
	printf("****************************************************\n");

	DWORD Status;
	DWORD *ThId_Philo=new DWORD[N];
	HANDLE *philo_h=new HANDLE[N];
	THREAD_ARGS *ThArgs_Philo=new THREAD_ARGS[N];

	//当前拿起的叉子数目
	g_philobuf_fork_num=0;

	mutex_g_buf_h=CreateMutex(NULL,FALSE,mutex_g_buf);
	int nCounter=0;

	for(nCounter=0;nCounter<N;nCounter++)
	{
		sem_perphilo_h[nCounter]=(HANDLE)CreateSemaphore(NULL,0,1,
			sem_perphilo_name[nCounter]);
	}
	//CreateThread
	for(nCounter=0;nCounter<N;nCounter++)
	{
		ThArgs_Philo[nCounter].id=nCounter;
		ThArgs_Philo[nCounter].maxnum=MAXNUM;
		philo_h[nCounter]=(HANDLE)CreateThread(NULL,0,philosopher,
			&ThArgs_Philo[nCounter],0,&ThId_Philo[nCounter]);
	}

	/* w
操作系统-PV原语(三) 一、哲学家进餐问题 由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题。 该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐。进餐毕,放下筷子继续思考。 1.利用记录型信号量解决哲学家解决问题 经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许 阅读详情

相关推荐

操作系统之经典进程同步问题

这里介绍三中进程同步问题:         1.生产者-消费者问题         2.读者-写者问题         3.哲学家进餐问题 一、生产者-消费者问题      1.问题描述:生产者-消费者模型描述的是有一群生产者进程在生产产品,并将这些产品提供给消费者进程并发进行,具备并发程序的典型特征。PCM为使生产者进程和消费者进程并发进行,在它们之间设置一个具有多个缓冲区的缓

honeysyt.的博客 1万+

进程同步之熟睡的理发师问题

熟睡的理发师问题(The Sleeping-Baber Problem)是操作系统中关于进程同步的一个经典问题,它涉及了到临界区保护、锁、信号量等方面的知识。在这篇博客中,我将具体讲解这个问题并用pthread库编码解决,相关pthread库的使用可查阅IEEE官方文档,我是传送门~~~。 问题描述:  某个理发店有个瞌睡虫理发师,只要没有顾客,他就会去睡觉;而整个理发店由两个区域组成:有N把...

August的博客 8064

经典进程同步与互斥问题

经典进程同步与互斥问题 文章目录经典进程同步与互斥问题一、生产者与消费者问题1.1 问题概述1.2 解决方法二、读者与写者问题2.1 问题概述2.2 解决方法三、哲学家进餐过程3.1 问题概述3.2 解决方法 一、生产者与消费者问题 1.1 问题概述 生产者与消费者互斥使用一个缓冲池 当缓冲池为空时,生产者才能写入数据 当缓冲池不为空时,消费者才能读取数据 1.2 解决方法 设置3个信号量:m...

qlzy的博客 2753

睡觉理发师问题——进程同步与死锁

     前些时看了一下操作系统原理,当我看到进程同步这里时有一个问题引发了我的思考:睡觉理发师问题。     具体如下:一个理发店里有一个理发师,一张理发椅子,多张等候的椅子,当没有顾客的时候,理发师就睡觉。当一个顾客来到店里时,如果理发师在睡觉,则叫醒理发师;否则便坐着等;如果等待的椅子都满了就离开。      我觉得这个问题可以引发许多关于操作系统的问题。比如:进程同步及程序执行

superyinyi的专栏 5824

Doris + Iceberg 实现高效数据湖分层:架构解析与最佳实践

本文深入解析了如何利用Doris与Iceberg构建高效的数据湖冷热分层架构。通过将高频访问的热数据存储在Doris中以实现毫秒级查询,同时将历史冷数据归档至低成本的Iceberg存储,该方案在保障查询性能的同时显著降低了总体拥有成本。文章详细阐述了从架构设计、自动化迁移到统一查询的最佳实践,为应对海量数据下的成本与性能平衡提供了实战指南。

weixin_29207533的博客 136

博途S7-1200与昆仑通态MCGS纯仿真联调实战指南

本文详细介绍了博途S7-1200与昆仑通态MCGS纯仿真联调的实战指南,包括环境搭建、配置步骤、通信桥接及故障排除。通过TIA Portal和MCGS Pro搭建的仿真环境,可实现80%以上的基础功能验证,适用于工业自动化学习和开发,大幅降低硬件投入成本。

weixin_26834815的博客 441

如何搭建pikachu靶场

Pikachu靶场本地搭建指南 下载安装PHPStudy并启动Apache/MySQL服务 获取Pikachu靶场源码并解压到网站根目录 配置数据库连接信息(修改config.inc.php文件) 创建pikachu数据库(用户名/密码设为root) 访问http://localhost/pikachu测试功能 常见问题:数据库连接失败需检查服务状态和配置信息,页面报错需检查PHP版本兼容性。建议使用PHP7.3/7.4版本,在隔离环境中搭建使用。 (150字)

2401_85351702的博客 1279

Cadence 17.4 PSpice仿真555定时器输出方波

这里利用555定时器组成多谐振荡器产生1Hz的方波并用PSpice仿真其输出的方波波形。555定时器是一种广泛应用的中规模集成电路。根据其内部组成的不同,可分为双极型(555B)和CMOS型(555C)两类。两种类型的定时器各有所长。双极型定时器具有较大的驱动能力,其输出电流可达200mA,可直接驱动发光二级管、扬声器、继电器等负载。而CMOS型定时器的输入阻抗高、功耗低。

tj_nonstoper的博客 1万+

经纬度转换为UTM坐标

UTM(通用横向墨卡托投影): 是一种以米为单位的坐标系统,用于地图和GPS导航。将地球划分为60个纵向的区域。每个区域宽6度,从赤道开始往南北两级方向划分。每个区域都有一个特定的字母。

weixin_45626706的博客 7282

基于嵌入式Linux设计的智能车库(GEC6818)

随着城市化进程的加快,传统停车管理方式存在效率低下、人工成本高、车主体验差等问题。为解决这些问题,本项目基于嵌入式Linux技术,设计并实现了一套智能车库管理系统。该系统采用GEC6818开发板作为核心控制器,运行Qt应用程序,并结合USB免驱摄像头进行车牌识别,RFID模块完成刷卡支付,SQLite数据库存储车主信息和停车记录。系统提供车主注册、用户管理、出入库管理、停车费结算、车辆查询等功能,并具备语音播报提示,提高用户体验。通过本系统,停车场管理更加高效、智能,有助于提升停车服务质量,减少人工干预,适

447

099、LLC谐振变换器的大信号建模

摘要:LLC谐振变换器的小信号模型在大信号工况(如启动、负载突变)下会失效,导致保护失灵、过冲等问题。通过状态空间平均法和分段线性化建立大信号模型,需关注谐振腔能量转移、模态切换条件及离散化实现。实际应用中,该模型可优化启动策略、精确设定保护阈值并验证环路补偿,但需注意变压器饱和等非线性因素。经验表明,大信号建模能显著提升设计可靠性,但需结合实验验证(误差<15%)和工具适配(如MATLAB离线仿真与C语言嵌入式调试)。三颗炸裂的MOSFET警示:深入掌握大信号建模是避免关键故障的必要手段。

Jack010169的博客 47

优化YOLOv8检测精度:Damo-YOLO的RepGFPN特征融合技术解析【YOLOv8】

YOLOv8在结构上依旧延续了自YOLOv4以来的CSPNet(Cross Stage Partial Network)和FPN(Feature Pyramid Network)的设计,结合了PANet(Path Aggregation Network)来增强特征的多尺度表达。然而,随着目标检测任务的复杂性增加,如何更有效地融合不同层级的特征成为提升检测性能的关键。Damo-YOLO中的RepGFPN引入了重参数化的思想,通过在训练和推理阶段对特征融合模块进行结构优化,显著提升了检测效果。

博客 1583

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: 关于Blog使用
下一篇: 字符串Hash函数
知行且执行
博客等级 码龄14年 38粉丝 73原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值