首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

皇后有关问题最快的解法(C语言)八皇后、十六皇后时间在毫秒级

2013-10-21 
皇后问题最快的解法(C语言)八皇后、十六皇后时间在毫秒级//皇后问题最快的解法(C语言)八皇后、十六皇后时间

皇后问题最快的解法(C语言)八皇后、十六皇后时间在毫秒级

//皇后问题最快的解法(C语言)八皇后、十六皇后时间在毫秒级
#include <windows.h># include<stdio.h># include<stdlib.h># include<time.h>#define O  134775813// TODO (xubo18056052430#1#): PB10210016  徐波LARGE_INTEGER lv,lv1,lv2,lv3,lv4;double totaltime,secondsPerTick;int step;/***********************************************************************************************/int dn(int n)          //分组,根据经验值产生,网搜得到--取下列值是比较好,返回不同的值对实验结果影响很大{    if (n < 100)return n;else if (n < 1000)return 40;else if (n < 10000)return 60;else if (n < 100000)return 90;elsereturn 150;}/***********************************************************************************************//***********************************************************************************************/int rand1 = (unsigned)time(NULL);        //rand1产生随机数int rand2(int range)                     //rand1线性同余随机数产生器{unsigned int x = 0x7fffffff, m, c = 1, a =O;m = x + 1;rand1 = (rand1 * a + 1)%m;double r =(double) rand1 / x;int r2 =  (int)(r * range);return r2;}/***********************************************************************************************//***********************************************************************************************/void swap(int &a, int &b){                                            //交换两值int c;c = a;a = b;b = c;}/***********************************************************************************************//***********************************************************************************************/int chongtu(int n, int line1[], int line2[]){                      //冲突int xubo = 0;for(int i = 0; i < n + n; i ++){if(line1[i] > 1){xubo = xubo + (line1[i] * (line1[i] - 1)) / 2;}if(line2[i] > 1){xubo = xubo + (line2[i] * (line2[i] - 1)) / 2;}}return xubo;}/***********************************************************************************************//***********************************************************************************************/int improve(int i, int j, int n, int q[], int line1[], int line2[])  //判断q[i]和q[j])交换后冲突的个数是否会减少{int xubo = 0;xubo = xubo + (1 - line1[i + q[i]]);xubo = xubo + (1 - line2[i - q[i] + n - 1]);xubo = xubo + (1 - line1[j + q[j]]);xubo = xubo + (1 - line2[j - q[j] + n - 1]);xubo = xubo + line1[i + q[j]];xubo = xubo + line2[i - q[j] + n - 1];xubo = xubo + line1[j + q[i]];xubo = xubo + line2[j - q[i] + n - 1];if(i + q[i] == j + q[j] || i - q[i] == j - q[j])xubo = xubo + 2;return xubo;}/***********************************************************************************************//***********************************************************************************************/void csh(int n, int m, int q[], int line1[], int line2[]){int i, end, rand3;bool *l1 = (bool *)malloc((n + n) * sizeof(bool));bool *l2 = (bool *)malloc((n + n) * sizeof(bool));for(i = 0; i < n; i ++){q[i] = i;line1[i] = 0;line2[i] = 0;l1[i] = false;l2[i] = false;}for(i = n; i < n + n; i ++){line1[i] = 0;line2[i] = 0;l1[i] = false;l2[i] = false;}for(i = 0, end = n; i < m; i ++, end --)   //初始化(0 ~ m - 1);前m行不会此时不会产生冲突{                                          //初始化后横竖无冲突,只要保证两斜线无冲突即可do{rand3 = i + rand2(end);}while(l1[i + q[rand3]] || l2[i - q[rand3] + n - 1]);swap(q[i], q[rand3]);line1[i + q[i]] ++;line2[i - q[i] + n - 1] ++;l1[i + q[i]] = true;l2[i - q[i] + n - 1] = true;}for(i = m, end = n - m; i < n; i ++, end--)                      //初始化line{rand3 = i + rand2(end);swap(q[i], q[rand3]);line1[i + q[i]] ++;line2[i - q[i] + n - 1] ++;}free(l1);free(l2);}/***********************************************************************************************//***********************************************************************************************/void work(int n, int m, int q[]){    QueryPerformanceFrequency( &lv );    secondsPerTick = 1000000.0 / lv.QuadPart;int temp, reduce, i, j;step = 0;int *line1 = (int *)malloc((n + n) * sizeof(int));    int *line2 = (int *)malloc((n + n) * sizeof(int));    QueryPerformanceCounter( &lv3 );csh(n, m, q, line1, line2);QueryPerformanceCounter( &lv4 );totaltime = secondsPerTick * (lv4.QuadPart-lv3.QuadPart);printf("\n初始化时间为:%e  s ", totaltime/1000000); //初始化时间temp = chongtu(n, line1, line2);//printf("冲突次数= %d\n", temp);while(temp > 0){reduce = 0;for(i = m; i < n; i ++){if(line1[i + q[i]] == 1 && line2[i - q[i] + n - 1] == 1)continue;else{for(j = 0; j < n; j ++){if(i != j){reduce = improve(i, j, n, q, line1, line2);if(reduce < 0)break;}}if(reduce < 0)   //可交换q[i]和q[j],使总的冲突减少break;}}if(reduce < 0){step ++;line1[i + q[i]] --;line2[i - q[i] + n - 1] --;line1[j + q[j]] --;line2[j - q[j] + n - 1] --;swap(q[i], q[j]);line1[i + q[i]] ++;line2[i - q[i] + n - 1] ++;line1[j + q[j]] ++;line2[j - q[j] + n - 1] ++;temp = temp + reduce;}else{        csh(n, m, q, line1, line2);             temp = chongtu(n, line1, line2);}}}/***********************************************************************************************//***********************************************************************************************/size_t **NQueen(size_t q_xubober)      //实验要求size_t **NQueen(size_t Queen_xubober){    LARGE_INTEGER lv,lv1,lv2;    double totaltime,secondsPerTick;    QueryPerformanceFrequency( &lv );    secondsPerTick = 1000000.0 / lv.QuadPart;unsigned int **ee = (unsigned int **)malloc(4 * sizeof(unsigned int *)), loop = 3, i, j;for(i = 1; i < 4; i ++)ee[i] = (unsigned int *)malloc((q_xubober + 1) * sizeof(unsigned int));int *q = (int *)malloc(q_xubober * sizeof(int));int m = q_xubober - dn(q_xubober);printf("\n问题大小N= %d  m= %d\n*************************************************************************\n", q_xubober, m);    for(i = 1; i < 4; i ++){        QueryPerformanceCounter( &lv1 );work(q_xubober, m, q);QueryPerformanceCounter( &lv2 );totaltime = secondsPerTick * (lv2.QuadPart-lv1.QuadPart);    printf("第%d次成功运行时间= %e s \n", i, totaltime/1000000);        printf("\n*************************************************************************\n");for(j = 0; j < q_xubober; j ++)ee[i][j + 1] = q[j] + 1;}return ee;}/***********************************************************************************************//***********************************************************************************************/int main(){unsigned int i, j, k = 0, **ee = NULL;int n;printf("请输入皇后问题N的大小:\n");scanf("%d", &n);printf("\n————————————————运行结果————————————————\n");if(n<=3){    printf("\错误!没有解!");    exit(1);                       //输入小于4的数报错跳出}if(n>=1000000000003){    printf("\错误!没有解!");    exit(1);                       //输入大于的数报错跳出}ee = NQueen(n);   if(n<=100){                       //如果输入的n小于等于100,者输出皇后摆放位置序列,否者不输出,因为n大序列长   for(i = 1; i <=3; i++)            //输出三个满足问题要求的皇后摆放位置序列try[1..3][1…n]。{    printf("\n\n第%d组解皇后摆放的位置序列位:\n",i);for(int j = 1; j < n + 1; j ++){for(k = 1; k < n + 1; k ++){if(k ==ee[i][j]){//printf("%d ",k);    //只输出列printf("(%d,%d) ",j,k);}  //输出行和列,第i个皇后摆放在(i,try[i])}        }        }}    printf("\n\n————————————————运行结果————————————————\n\n\n");system("pause");return 0;}/***********************************************************************************************/// TODO (xubo18056052430#1#): PB10210016  徐波

热点排行