zoukankan      html  css  js  c++  java
  • 无向图:查找最小环集合(最短路径回溯算法)

             在无向图中查找最小环,就像需要查找一个蜂窝中所有孔洞,如果只查找数目,可以利用欧拉公式,若查找到所有环,需要更进一步的搜索。

             方法:寻找到所有顶点的最短路径,对每一个顶点,取出环,循环删除顶点,输出所有最小环。

             注意:拓扑图具有位置可变性,不影响图结构的拓扑变化。所以此方法,只能找到拓扑最小环,若想找到距离最小环,需要对边进行加权。

             


            原文:找出无向图中所有环的算法。代码也转自于作者。

           

    图片实例:

          

    code:

           

    bool findAllLoop(int argc, char* argv[]);
    
    //查找所有路径的算法是成功的;但最短路径不能保证找到最小环
    int main(int argc, char* argv[])
    {
    	findAllLoop(argc, argv);
    	return 0;
    }
    
    bool findAllLoop(int argc, char* argv[]){
    
    	//if (argc != 5)
    	{
    		printf("	This algorithm require 3 parameters"
    			"
    		1:the size of eage"
    			"
    		2:the filename contain eage-data"
    			"
    		3:the size of vertax"
    			"
    		4:the filename contain vertax-data
    ");
    		//exit(0);
    	}
    	//eage_size = atoi(argv[1]);
    	//strcat(filename_eage, argv[2]);
    	//vertax_size = atoi(argv[3]);
    	//strcat(filename_vertax, argv[4]);
    	wishchin::eage_size = 22;//边的个数
    	//strcat(filename_eage, argv[2]);
    
    	std::string filename_eages("D:/DataSet/RsData/loopFind/houseAdj.txt");
    
    	wishchin::vertax_size = 17;//顶点个数
    	//strcat(filename_vertax, argv[4]);
    	std::string filename_vertaxs("D:/DataSet/RsData/loopFind/houseVotex.txt");
    	//printf("eage_size : %d, vertax_size : %d, filename-eage : %s, filename-vertax : %s
    ",
    				wishchin::eage_size, wishchin::vertax_size, filename_eages, wishchin::filename_vertax);
    
    	wishchin::readEageDataFromFile(filename_eages);
    	wishchin::readVertaxDataFromFile(filename_vertaxs);
    
    	wishchin::createAdjacentMatrix();
    
    	wishchin::DFSTraverse();
    	//test_stack();  
    
    	return true;
    }
    
    namespace wishchin{
    
    	void readEageDataFromFile( std::string filename_eages)
    	{
    		FILE* f_read;
    		if (NULL == (f_read = fopen(filename_eages.c_str(), "r")))
    		{
    			printf("open file(%s) error!
    ", filename_eages.c_str());
    			exit(0);
    		}
    		//create dynamic array for storing original data form file @filename  
    		eage_set = (int**)malloc(sizeof(int*) * (eage_size + 1));
    		if (!eage_set)
    		{
    			printf("malloc error: eage_set**
    ");
    			exit(0);
    		}
    		int i;
    		for (i = 1; i <= eage_size; i++)
    		{
    			eage_set[i] = (int*)malloc(sizeof(int) * (2 + 1));
    			if (!eage_set[i])
    			{
    				printf("eage_set[%d] malloc error", i);
    				exit(0);
    			}
    		}
    
    		//read original data from file  //直接读入边的集合
    		for (i = 1; i <= eage_size; i++)
    		{
    			if (2 != fscanf(f_read, "%d %d", &eage_set[i][1], &eage_set[i][2]))
    			{
    				printf("fscanf error: %d
    ", i);
    				exit(0);
    			}
    			printf("%d	%d
    ", eage_set[i][1], eage_set[i][2]);
    		}
    
    		//test  
    		printf("
     show the origin data from file
    ");
    		for (i = 1; i <= eage_size; i++)
    		{
    			printf("%d	%d
    ", eage_set[i][1], eage_set[i][2]);
    		}
    		printf("
    ");
    		//test END  
    	}
    
    	void readEageDataFromFile()
    	{
    		FILE* f_read;
    		if (NULL == (f_read = fopen(filename_eage, "r")))
    		{
    			printf("open file(%s) error!
    ", filename_eage);
    			exit(0);
    		}
    		//create dynamic array for storing original data form file @filename  
    		eage_set = (int**)malloc(sizeof(int*) * (eage_size + 1));
    		if (!eage_set)
    		{
    			printf("malloc error: eage_set**
    ");
    			exit(0);
    		}
    		int i;
    		for (i = 1; i <= eage_size; i++)
    		{
    			eage_set[i] = (int*)malloc(sizeof(int) * (2 + 1));
    			if (!eage_set[i])
    			{
    				printf("eage_set[%d] malloc error", i);
    				exit(0);
    			}
    		}
    
    		//read original data from file  //直接读入边的集合
    		for (i = 1; i <= eage_size; i++)
    		{
    			if (2 != fscanf(f_read, "%d %d", &eage_set[i][1], &eage_set[i][2]))
    			{
    				printf("fscanf error: %d
    ", i);
    				exit(0);
    			}
    		}
    
    		//test  
    		printf("
     show the origin data from file
    ");
    		for (i = 1; i <= eage_size; i++)
    		{
    			printf("%d	%d
    ", eage_set[i][1], eage_set[i][2]);
    		}
    		printf("
    ");
    		//test END  
    	}
    
    	void readVertaxDataFromFile()
    	{
    		//create the dynamic array for saving vertax-set information  
    		vertax_set = (char**)malloc(sizeof(char*) * (vertax_size + 1));
    		if (!vertax_set)
    		{
    			printf("vertax_set malloc error");
    			exit(0);
    		}
    		int i;
    		for (i = 1; i <= vertax_size; i++)
    		{
    			vertax_set[i] = (char*)malloc(sizeof(char) * (20 + 1));
    			if (!vertax_set[i])
    			{
    				printf("vertax_set[%d] malloc error");
    				exit(0);
    			}
    		}
    
    		//open file  
    		FILE* f_read;
    		if (NULL == (f_read = fopen(filename_vertax, "r")))
    		{
    			printf("open file(%s) error", filename_vertax);
    			exit(0);
    		}
    
    		//read vertax-set information  
    		for (i = 1; i <= vertax_size; i++)
    		{
    			if (1 != fscanf(f_read, "%s ", vertax_set[i]))
    			{
    				printf("fscanf vertax_set[%d] error", i);
    				exit(0);
    			}
    		}
    
    		//test  
    		for (i = 1; i <= vertax_size; i++)
    		{
    			printf("%s
    ", vertax_set[i]);
    		}
    		printf("
    ");
    		//test END  
    	}
    
    	void readVertaxDataFromFile( std::string filename_vertaxs )
    	{
    		//create the dynamic array for saving vertax-set information  
    		vertax_set = (char**)malloc(sizeof(char*) * (vertax_size + 1));
    		if (!vertax_set)
    		{
    			printf("vertax_set malloc error");
    			exit(0);
    		}
    		int i;
    		for (i = 1; i <= vertax_size; i++)
    		{
    			vertax_set[i] = (char*)malloc(sizeof(char) * (20 + 1));
    			if (!vertax_set[i])
    			{
    				printf("vertax_set[%d] malloc error");
    				exit(0);
    			}
    		}
    
    		//open file  
    		FILE* f_read;
    		if (NULL == (f_read = fopen(filename_vertaxs.c_str(), "r")))
    		{
    			printf("open file(%s) error", filename_vertaxs.c_str());
    			exit(0);
    		}
    
    		//read vertax-set information  
    		for (i = 1; i <= vertax_size; i++)
    		{
    			if (1 != fscanf(f_read, "%s ", vertax_set[i]))
    			{
    				printf("fscanf vertax_set[%d] error", i);
    				exit(0);
    			}
    		}
    
    		//test  
    		for (i = 1; i <= vertax_size; i++)
    		{
    			printf("%s
    ", vertax_set[i]);
    		}
    		printf("
    ");
    		//test END  
    	}
    
    	void createAdjacentMatrix()
    	{
    		//create the dynamic array for saving adjcaent matrix  
    		adjacentMatrix = (int**)malloc(sizeof(int*) * (vertax_size + 1));
    		if (!adjacentMatrix)
    		{
    			printf("adjacentMatrix** malloc error");
    			exit(0);
    		}
    		int i;
    		for (i = 1; i <= vertax_size; i++)
    		{
    			adjacentMatrix[i] = (int*)malloc(sizeof(int) * (vertax_size + 1));
    			if (!adjacentMatrix[i])
    			{
    				printf("adjacentMatrix[%d] malloc error");
    				exit(0);
    			}
    		}
    		//initial the value of adjacentMatrix  
    		int j;
    		for (i = 1; i <= vertax_size; i++)
    		{
    			for (j = 1; j <= vertax_size; j++)
    			{
    				adjacentMatrix[i][j] = 0;
    			}
    		}
    
    		//set the value for adjacentMatrix   
    		for (i = 1; i <= eage_size; i++)
    		{
    			adjacentMatrix[eage_set[i][1]][eage_set[i][2]] = 1;
    			adjacentMatrix[eage_set[i][2]][eage_set[i][1]] = 1;
    		}
    
    		//test  
    		printf("
     show the information about adjacent matrix: 
    ");
    		for (i = 1; i <= vertax_size; i++)
    		{
    			for (j = 1; j <= vertax_size; j++)
    			{
    				printf("%d ", adjacentMatrix[i][j]);
    			}
    			printf("
    ");
    		}
    		//test END  
    	}
    }
    
    namespace wishchin{
    
    	int loop_count;
    	int heap;
    	int innerStep = 0;
    	int temp;
    	int isRecall;
    	SequenceStack loop_stack;
    	int pop_value;
    	void DFS(int startVertax)
    	{
    		setVisitedFlag(startVertax, 1);
    		int nextVertax;
    		push_stack(&loop_stack, startVertax);
    		nextVertax = firstAdjacentVertax(startVertax);
    		innerStep++;
    		for (;;)
    		{
    			if (nextVertax != -1)
    			{
    				if (visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep == 2)
    				{
    					nextVertax = nextAdjacentVertax(startVertax, nextVertax);
    					continue;
    				}
    				else if (visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep != 2)
    				{
    					print_stack(loop_stack);
    					nextVertax = nextAdjacentVertax(startVertax, nextVertax);
    					continue;
    				}
    				else if (visitedFlag[nextVertax] == 0)
    				{
    					DFS(nextVertax);
    				}
    				if (isRecall == 1)
    				{
    					innerStep--;
    					temp = nextVertax;
    					nextVertax = nextAdjacentVertax(startVertax, nextVertax);
    					pop_stack(&loop_stack, &pop_value);
    					setVisitedFlag(temp, 0);
    					isRecall = 0;
    					continue;
    				}
    				nextVertax = nextAdjacentVertax(startVertax, nextVertax);
    			}
    			else if (nextVertax == -1)
    			{
    				isRecall = 1;
    				break;
    			}
    		}
    	}
    	void DFSTraverse()
    	{
    		initialVisitedFlagArray();
    		initializeSequenceStack(&loop_stack);
    		int i;
    		for (heap = 1; heap <= vertax_size; heap++)
    		{
    			for (i = 1; i <= vertax_size; i++)
    			{
    				visitedFlag[i] = 0;
    			}
    			/*
    			printf("print the visitedFlag array: ");
    			for( i = 1; i <= vertax_size; i++ )
    			{
    			printf("%d ", visitedFlag[i]);
    			}
    			printf("
    ");
    			*/
    			if (visitedFlag[heap] == 0)
    			{
    				printf("
    -------------------the loop start and end with %d----------------
    ", heap);
    				clear_stack(&loop_stack);
    				innerStep = 0;
    				//printf("isRecall : %d, findLoop : %d, hasOthers : %d
    ", isRecall, findLoop, hasOthers);  
    				isRecall = 0;
    				DFS(heap);
    			}
    		}
    	}
    	void initialVisitedFlagArray()
    	{
    		visitedFlag = (int*)malloc(sizeof(int) * (vertax_size + 1));
    		if (!visitedFlag)
    		{
    			printf("visitedFlag* malloc error");
    			exit(0);
    		}
    		int i;
    		for (i = 1; i <= vertax_size; i++)
    			visitedFlag[i] = 0;
    	}
    	void printVisitedVertax(int vertaxID)
    	{
    		printf("visited: %d 
    ", vertaxID);
    	}
    	void setVisitedFlag(int vertaxID, int value)
    	{
    		visitedFlag[vertaxID] = value;
    	}
    	int firstAdjacentVertax(int vertaxID)
    	{
    		int i;
    		for (i = 1; i <= vertax_size; i++)
    		{
    			if (adjacentMatrix[vertaxID][i] == 1)
    				return i;
    		}
    		return -1;
    	}
    	int nextAdjacentVertax(int vertaxID, int nextVertaxID)
    	{
    		int i;
    		for (i = nextVertaxID + 1; i <= vertax_size; i++)
    		{
    			if (adjacentMatrix[vertaxID][i] == 1)
    				return i;
    		}
    		return -1;
    	}
    	void initializeSequenceStack(SequenceStack* stack)
    	{
    		stack->base = (int*)malloc(sizeof(int) * (vertax_size + 1));
    		if (!stack->base)
    		{
    			printf("Sequence stack malloc error!
    ");
    			exit(0);
    		}
    		stack->top = stack->base;
    		stack->stackSize = vertax_size;
    	}
    	void pop_stack(SequenceStack* stack, int* value)
    	{
    		if (empty_stack(*stack) == 1)
    		{
    			printf("stack is empty , can not to pop!
    ");
    			exit(0);
    		}
    		*value = *(--(stack->top));
    	}
    	void push_stack(SequenceStack* stack, int value)
    	{
    		*(stack->top) = value;
    		(stack->top)++;
    	}
    	int empty_stack(SequenceStack stack)
    	{
    		return stack.top == stack.base ? 1 : 0;
    	}
    	void print_stack(SequenceStack stack)
    	{
    		int temp = *(stack.base);
    		while (stack.top != stack.base)
    		{
    			printf("%d->", *((stack.base)++));
    		}
    		printf("%d
    ", temp);
    	}
    	void clear_stack(SequenceStack* stack)
    	{
    		stack->top = stack->base;
    	}
    }

    测试数据:

          houseAdj.txt:

    1 2
    2 3
    3 4
    1 5
    2 6
    3 7
    4 8
    5 6
    5 9
    7 8
    7 12
    9 10
    10 11
    11 12
    12 17
    9 13
    10 14
    11 15
    17 16
    13 14
    14 15
    15 16


          housevotex.txt

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17


    程序输出:




           



  • 相关阅读:
    关于springMVC转换json出现的异常
    jQuery实现,动态自动定位弹窗。JS分页,Ajax请求
    servlet为什么要配置web.xml
    Jmeter系列(4)- Jmeter 脚本录制
    后缀数组模板
    NOIP2016 玩脱记
    TERSUS无代码开发(笔记21)-流程执行顺序思考(转载)
    ===>===>===>特色思TERSUS常用功能整理
    TERSUS无代码开发(笔记20)-本地开发测试mysql数据库连接
    TERSUS无代码开发(笔记19)-mysql-connector-java-5.-bin.jar下载方法
  • 原文地址:https://www.cnblogs.com/wishchin/p/9199872.html
Copyright © 2011-2022 走看看