|
楼主 |
发表于 2007-7-31 04:41:43
|
显示全部楼层
2. 程序设计
申明定义一些程序所需要的各种状态的枚举及描述
- #define NUM 5
- enum var_attr { NAME=0, COLOR, PAT, DRINK, FRUIT };
- char *str_attr[] = { "Name", "Color", "Pat", "Drink", "Frui" };
- enum val_relation { LEFT=-1, IS=0, RIGHT=1 };
- enum val_name { QIAN=0, WEN, CHEN, ZHAO, JIANG };
- char *str_name[] = { "Qian", "Wen", "Chen", "Zhao", "Jiang" };
- enum val_color { RED=0, GREEN, WHITE, YELLOW, BLUE };
- char *str_color[] = { "Red", "Green", "White", "Yellow", "Blue" };
- enum val_pat { DOG=0, BIRD, FISH, CAT, SNAKE };
- char *str_pat[] = { "Dog", "Bird", "Fish", "Cat", "Snake" };
- enum val_drink { TEA=0, COFFEE, MILK, XIANGBIN, WATER };
- char *str_drink[] = { "Tea", "Coffee", "Milk", "Bubbly", "Water" };
- enum val_fruit { WATERMELON=0, ORANGE, LIUDING, APPLE, BANANA };
- char *str_fruit[] = { "W.Melon", "Orange", "LiuDing", "Apple", "Banana" };
复制代码 因为题目的条件是一些钱小姐穿红色的衣服, 养鱼的小姐隔壁吃柳丁,
吃苹果的小姐喝香槟, 穿绿衣服的站在穿白衣服的左边 之类的条件,
当程序穷举出所有排列组合的时候,
就需要有个函数来测试每种组合是否符合所有的条件
看看check_okay函数, 输入参数是所有的状态数组组合, 返回是否Okay- int check_okay( int *name, int *color, int *pat, int *drink, int *fruit )
- {
- //钱小姐穿红色的衣服
- if( !check_relation( name, QIAN, color, RED, IS ) )
- return FALSE;
- //翁小姐养了一只狗
- if( !check_relation( name, WEN, pat, DOG, IS ) )
- return FALSE;
- //陈小姐喝茶
- if( !check_relation( name, CHEN, drink, TEA, IS ) )
- return FALSE;
- //穿绿衣服的站在穿白衣服的左边
- if( !check_relation( color, GREEN, color, WHITE, LEFT ) )
- return FALSE;
- //穿绿衣服的小姐喝咖啡
- if( !check_relation( color, GREEN, drink, COFFEE, IS ) )
- return FALSE;
- //吃西瓜的小姐养鸟
- if( !check_relation( fruit, WATERMELON, pat, BIRD, IS ) )
- return FALSE;
- //穿黄衣服的小姐吃柳丁
- if( !check_relation( color, YELLOW, fruit, LIUDING, IS ) )
- return FALSE;
- //站在中间的小姐喝牛奶
- if( get_location( drink, MILK )!=2 )
- return FALSE;
- //赵小姐站在最左边
- if( get_location( name, ZHAO )!=0 )
- return FALSE;
- //吃桔子的小姐站在养猫的隔壁
- if( !( check_relation( fruit, ORANGE, pat, CAT, LEFT ) ||
- check_relation( fruit, ORANGE, pat, CAT, RIGHT ) ) )
- return FALSE;
- //养鱼的小姐隔壁吃柳丁
- if( !( check_relation( pat, FISH, fruit, LIUDING, LEFT ) ||
- check_relation( pat, FISH, fruit, LIUDING, RIGHT ) ) )
- return FALSE;
- //吃苹果的小姐喝香槟
- if( !check_relation( fruit, APPLE, drink, XIANGBIN, IS ) )
- return FALSE;
- //江小姐吃香蕉
- if( !check_relation( name, JIANG, fruit, BANANA, IS ) )
- return FALSE;
- //赵小姐站在穿蓝衣服的隔壁
- if( !( check_relation( name, ZHAO, color, BLUE, LEFT ) ||
- check_relation( name, ZHAO, color, BLUE, RIGHT ) ) )
- return FALSE;
- //只喝开水的小姐站在吃桔子的隔壁
- if( !( check_relation( drink, WATER, fruit, ORANGE, LEFT ) ||
- check_relation( drink, WATER, fruit, ORANGE, RIGHT ) ) )
- return FALSE;
- return TRUE;
- };
复制代码 get_location函数是返回某一个数组中, 指定状态的位置- int get_location( int *attr, int value )
- {
- int i;
- for( i=0; i<NUM; i++ )
- {
- if( value==attr )
- {
- return i;
- }
- }
- return 0;
- };
复制代码 check_relation函数就是用来检测两组属性的关系, 我们设计的站位是[左 0-1-2-3-4 右]
来实现条件中所说的, 什么怎么样的人怎么样(IS=0),
什么怎么样的人在怎么样的人左边(LEFT=-1), 右边(RIGHT=1), 邻居(LEFT||RIGHT)- int check_relation( int *attr1, int value1, int *attr2, int value2, int relation )
- {
- int location1, location2;
- int location;
- location1 = get_location( attr1, value1 );
- location2 = get_location( attr2, value2 );
- location = location1 - location2 ;
- if( location == relation )
- return TRUE;
- else
- return FALSE;
- };
复制代码 程序的函数介绍完毕了, 现在看看主函数, 傻吧? 穷举都这个样!!- int main( void )
- {
- int name[NUM], color[NUM], pat[NUM], drink[NUM], fruit[NUM];
- int i;
- for( i=0; i<NUM; i++ )
- {
- name = 0;
- color = 0;
- pat = 0;
- drink = 0;
- fruit = 0;
- }
- while( mksort(name, NUM) )
- {
- while( mksort(color, NUM) )
- {
- while( mksort(pat, NUM) )
- {
- while( mksort(drink, NUM) )
- {
- while( mksort(fruit, NUM) )
- {
- if( check_okay( name, color, pat, drink, fruit ) )
- {
- display_info( name, color, pat, drink, fruit );
- }
- }
- }
- }
- }
- }
- return 0;
- };
复制代码 挖咔咔, 如果觉得闷地话, 就在最里面的 while里面显示些东西解解闷
( 如果显示器一直盯着看的话, 显卡的显示将是运算的瓶颈,
切换到别的tty上, 眼不见, 让它后台飞快运行吧 )
4. 运算结果
ThinkPad X20 的主频是 Piii 500MHz
$ more /proc/cpuinfo
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 8
model name : Pentium III (Coppermine)
stepping : 3
cpu MHz : 500.000
cache size : 256 KB
... ...
内寸也只有 128M
$ more /proc/meminfo
MemTotal: 126132 kB
MemFree: 2440 kB
Buffers: 36352 kB
Cached: 35056 kB
... ...
我运行起来, 然后去做论文答辩的幻灯片, 然后去看别人答辩论文,
然后自己参加答辩论文, 然后去拍毕业照, 然后庆祝lynn6.1生日,
然后... ...
四天呐, 居然还没有算完!!
实在恼火, 换其他电脑, 我手头的最高主频的CPU也才1.4GHz...
借只鸡, 下个蛋吧;-P
一台 SUN Fire x4100 的服务器,
有 2颗 2.4GHz的主频 AMD Opteron 280的双核芯片,
配 4G 内存, 是 Solaris 10 Update 3 for x86/x64系统
嘿嘿, 其实程序占的内寸不超过 1M的...
编译的时候用 gcc 的 3级优化处理
$ make
gcc -O3 -c mksort.c
gcc -O3 -o 5kind main.c mksort.o
现在开始穷举贰佰肆拾捌亿捌仟叁佰贰拾万次了, 睡觉去了
O_O => o_o => *_* => x_x => zzZZ ... ZZzz => p_- => O_O! 要去看运算结果了
整整 3小时 17分钟 22秒, 终于盼到了
( 话外音: dorainm真是宇宙猛人呐, 250亿次的穷举... )
$ more result.txt
------------- start informations -------------
Name Color Pat Drink Frui
----------------------------------------------
Zhao Yellow Cat Water LiuDing
Chen Blue Fish Tea Orange
Qian Red Bird Milk W.Melon
Jiang Green Snake Coffee Banana
Wen White Dog Bubbly Apple
----------------------------------------------
只有一种结果啊, 养蛇的果然是江小姐
文章中出现的程序附件
其实, 兜售此文是想和大家一起来优化算法, 提高这穷举算法的速度的!
当然, 也欢迎数学方法来改变程序结构, 增加效率, dorainm在此抛砖引玉 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
×
|