找回密码
 欢迎注册
楼主: 056254628

[讨论] 一种棋类游戏

[复制链接]
发表于 2009-10-16 09:20:53 | 显示全部楼层
修改后的代码如下: 此外如果内存还是太小,宏STABLE还可以改小一半左右.但是需要注意STABLE和WALK必须互素.
  1. // chp.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <stdlib.h>
  7. #define N 8
  8. #define BITS (N*N)
  9. typedef unsigned long long SET;
  10. SET nghb[BITS];
  11. #define EMPTY_SET 0LL
  12. #define INDEX(x,y) ((x)*N+(y))
  13. #define GET_X(ind) ((ind)/N)
  14. #define GET_Y(ind) ((ind)%N)
  15. #define ADD_INDEX(s, ind) ((s)|=1LL<<(ind))
  16. #define TEST_INDEX(s, ind) (((s)&(1LL<<(ind)))!=0)
  17. #define CORNMASK (3|(3<<N))
  18. #define TEST_BIT(x, b) (((x)&(1LL<<(b)))!=0)
  19. #define SET_BIT(x, b) ((x)|=(1LL<<(b)))
  20. #define GET_CORN(x) (((x)&3)| (((x)>>N)&3)<<2)
  21. #define DISP_CORN(x) (((x)&3)| ((((x)>>2)&3)<<N))
  22. #define ECVALUE(x) (((x)&~CORNMASK)|DISP_CORN(cr[GET_CORN(x)]))
  23. #define STABLE 50000033
  24. #define WALK 1000
  25. int hc;
  26. int ec;
  27. int nec;
  28. int lec;
  29. long long htable[STABLE];
  30. //long long htable2[STABLE];
  31. char cr[16]={1,-1,-1,-1,-1,-1,-1,-1,4,-1,5,-1,3,-1,11,7};
  32. char rc[16]={-1,0,-1,12,8,10,-1,15,-1,-1,-1,14,-1,-1,-1,-1};
  33. FILE *fout;
  34. void dump(long long v)
  35. {
  36. int i,j;
  37. for(i=0;i<N;i++){
  38. for(j=0;j<N;j++){
  39. if(TEST_BIT(v,i*N+j)){
  40. fprintf(fout,"1 ");
  41. }else{
  42. fprintf(fout,"0 ");
  43. }
  44. }
  45. fprintf(fout,"\n");
  46. }
  47. fprintf(fout,"\n");
  48. }
  49. void copy_ec(long long *p)
  50. {
  51. int i,t;
  52. for(i=0,t=0;i<STABLE;i++){
  53. if(htable[i]!=-1LL){
  54. if(cr[GET_CORN(htable[i])]!=-1){
  55. p[t++]=htable[i];
  56. }
  57. }
  58. }
  59. }
  60. void dump_ec(long long htable[])
  61. {
  62. int i;
  63. fout = fopen("dump.txt","w");
  64. for(i=0;i<STABLE;i++){
  65. if(htable[i]!=-1LL){
  66. if(cr[GET_CORN(htable[i])]!=-1){
  67. dump(htable[i]);
  68. }
  69. }
  70. }
  71. fclose(fout);
  72. }
  73. void init()
  74. {
  75. memset(htable,-1,sizeof(htable));
  76. // memset(htable2,-1,sizeof(htable2));
  77. }
  78. int hash(SET s)
  79. {
  80. return (int)(s%STABLE);
  81. }
  82. int add_hash(long long htable[],long long key, bool eq)
  83. {
  84. int v=hash(key);
  85. long long ev;
  86. ev=ECVALUE(key);
  87. if(hc>=STABLE){
  88. fprintf(stderr,"out of hash table range\n");
  89. exit(-1);
  90. }
  91. do{
  92. if(htable[v]==-1LL){
  93. if(eq){
  94. htable[v]=ev;nec++;
  95. }else{
  96. htable[v]=key;
  97. ec++;
  98. }
  99. hc++;
  100. return v;
  101. }else if(htable[v]!=key&&htable[v]!=ev){
  102. v=(v+WALK)%STABLE;
  103. }else{
  104. if(eq){
  105. assert(htable[v]==ev);
  106. }else{
  107. assert(htable[v]==key);
  108. }
  109. return v;
  110. }
  111. }while(1);
  112. }
  113. int query_hash_entry(long long htable[],long long key)///return index to hash table
  114. {
  115. long long ev=ECVALUE(key);
  116. int v=hash(key);
  117. do{
  118. if(htable[v]==-1LL)return v;
  119. if(htable[v]==key||htable[v]==ev)
  120. return v;
  121. v=(v+WALK)%STABLE;
  122. }while(1);
  123. }
  124. void init_neighbour()
  125. {
  126. int i,j;
  127. for(i=0;i<N;i++){
  128. for(j=0;j<N;j++){
  129. SET s=EMPTY_SET;
  130. ADD_INDEX(s,INDEX(i,j));
  131. if(i>0&&j>0){
  132. ADD_INDEX(s,INDEX(i-1,j-1));
  133. }
  134. if(i>0){
  135. ADD_INDEX(s,INDEX(i-1,j));
  136. }
  137. if(j>0){
  138. ADD_INDEX(s,INDEX(i,j-1));
  139. }
  140. if(i>0&&j<N-1){
  141. ADD_INDEX(s,INDEX(i-1,j+1));
  142. }
  143. if(j<N-1){
  144. ADD_INDEX(s,INDEX(i,j+1));
  145. }
  146. if(i<N-1&&j>0){
  147. ADD_INDEX(s,INDEX(i+1,j-1));
  148. }
  149. if(i<N-1){
  150. ADD_INDEX(s,INDEX(i+1,j));
  151. }
  152. if(i<N-1&&j<N-1){
  153. ADD_INDEX(s,INDEX(i+1,j+1));
  154. }
  155. nghb[INDEX(i,j)]=s;
  156. }
  157. }
  158. }
  159. #if 0
  160. void visit(long long neighb)
  161. {
  162. int i;
  163. int e=query_hash_entry(htable,neighb);
  164. if(htable[e]==neighb){
  165. int ee=query_hash_entry(htable2,neighb);
  166. if(htable2[ee]==-1){
  167. htable2[ee]=neighb;
  168. lec++;
  169. for(i=0;i<BITS;i++){
  170. if(TEST_BIT(neighb,i)==0){
  171. long long newneighb=neighb;
  172. newneighb|=nghb[i];
  173. visit(newneighb);
  174. }
  175. }
  176. }
  177. }else{
  178. for(i=0;i<BITS;i++){
  179. if(TEST_BIT(neighb,i)==0){
  180. long long newneighb=neighb;
  181. newneighb|=nghb[i];
  182. int e2=query_hash_entry(htable,newneighb);
  183. if(htable[e2]==newneighb){
  184. visit(newneighb);
  185. break;
  186. }
  187. }
  188. }
  189. }
  190. }
  191. #endif
  192. int query(long long neighb)
  193. {
  194. int e=query_hash_entry(htable,neighb);
  195. if(htable[e]!=-1)
  196. return e;
  197. int i;
  198. for(i=0;i<BITS;i++){
  199. if(TEST_BIT(neighb,i)==0){
  200. long long newneighb=neighb;
  201. newneighb|=nghb[i];
  202. int r=query(newneighb);
  203. if(htable[r]==newneighb)
  204. break;
  205. }
  206. }
  207. if(i<BITS){///find any status is newneighb
  208. return add_hash(htable,neighb,true);
  209. }else{
  210. return add_hash(htable,neighb,false);
  211. }
  212. }
  213. int cmpll(const void *p,const void *q)
  214. {
  215. const long long *lp=(const long long *)p;
  216. const long long *lq=(const long long *)q;
  217. if(*lp==*lq)return 0;
  218. if(*lp<*lq)return -1;
  219. return 1;
  220. }
  221. int _tmain(int argc, _TCHAR* argv[])
  222. {
  223. int i,j;
  224. init();
  225. init_neighbour();
  226. int s=query(0LL);
  227. if(htable[s]==0LL){
  228. printf("First fail\n");
  229. }else{
  230. printf("First successful\n");
  231. }
  232. printf("Total table size %d\n",hc);
  233. printf("Total eq stat found %d\n",ec);
  234. printf("Total neq stat found %d\n",nec);
  235. #if 0
  236. for(i=0;i<BITS;i++){
  237. long long r=nghb[i];
  238. printf("%d set={ ",i);
  239. for(j=0;j<BITS;j++){
  240. if(!TEST_BIT(r,j)){
  241. long long newneighb=r;
  242. newneighb|=nghb[j];
  243. int u=query_hash_entry(htable,newneighb);
  244. if(htable[u]==newneighb){
  245. printf("%d ",j);
  246. }
  247. }
  248. }
  249. printf("}\n");
  250. }
  251. #endif
  252. return 0;
  253. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 09:23:20 | 显示全部楼层
发现宏STABLE已经不能再小了(除非修改代码再考虑对称性),实际上最后使用的数目为31816105.
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 14:33:33 | 显示全部楼层
如果在vc6下,将所有long long 改为__int64. mathe 发表于 2009-10-16 09:17
我照做了,但是LL还报错,于是1LL->(__int64)1,0LL->(__int64)0 C:\vc6>cl ch.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86 Copyright (C) Microsoft Corp 1984-1998. All rights reserved. ch.cpp Microsoft (R) Incremental Linker Version 6.00.8168 Copyright (C) Microsoft Corp 1992-1998. All rights reserved. /out:ch.exe ch.obj ch.exe : warning LNK4084: total image size 800043008 exceeds max (268435456); image may not run

ch.cpp

7.25 KB, 下载次数: 3, 下载积分: 金币 -1 枚, 经验 1 点, 下载 1 次

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 15:03:57 | 显示全部楼层
你可以试着将htable的内存初始化改成动态分配(用malloc)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 20:18:53 | 显示全部楼层
堆栈溢出?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 20:29:29 | 显示全部楼层
不是说运行很长时间? 我把21楼改成下面,马上运行结束。 First fail Total table size 0 Total eq stat found 0 Total neq stat found 0
  1. // chp.cpp : Defines the entry point for the console application.
  2. //
  3. //#include "stdafx.h"
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #include <stdlib.h>
  8. #define N 8
  9. #define BITS (N*N)
  10. typedef unsigned __int64 SET;
  11. SET nghb[BITS];
  12. #define EMPTY_SET (__int64)0
  13. #define INDEX(x,y) ((x)*N+(y))
  14. #define GET_X(ind) ((ind)/N)
  15. #define GET_Y(ind) ((ind)%N)
  16. #define ADD_INDEX(s, ind) ((s)|=(__int64)1<<(ind))
  17. #define TEST_INDEX(s, ind) (((s)&((__int64)1<<(ind)))!=0)
  18. #define CORNMASK (3|(3<<N))
  19. #define TEST_BIT(x, b) (((x)&((__int64)1<<(b)))!=0)
  20. #define SET_BIT(x, b) ((x)|=((__int64)1<<(b)))
  21. #define GET_CORN(x) (((x)&3)| (((x)>>N)&3)<<2)
  22. #define DISP_CORN(x) (((x)&3)| ((((x)>>2)&3)<<N))
  23. #define ECVALUE(x) (((x)&~CORNMASK)|DISP_CORN(cr[GET_CORN(x)]))
  24. #define STABLE 50000033
  25. #define WALK 1000
  26. int hc;
  27. int ec;
  28. int nec;
  29. int lec;
  30. __int64 *htable=(__int64 *)malloc(sizeof(__int64)*STABLE);
  31. //__int64 htable2[STABLE];
  32. char cr[16]={1,-1,-1,-1,-1,-1,-1,-1,4,-1,5,-1,3,-1,11,7};
  33. char rc[16]={-1,0,-1,12,8,10,-1,15,-1,-1,-1,14,-1,-1,-1,-1};
  34. FILE *fout;
  35. void dump(__int64 v)
  36. {
  37. int i,j;
  38. for(i=0;i<N;i++){
  39. for(j=0;j<N;j++){
  40. if(TEST_BIT(v,i*N+j)){
  41. fprintf(fout,"1 ");
  42. }else{
  43. fprintf(fout,"0 ");
  44. }
  45. }
  46. fprintf(fout,"\n");
  47. }
  48. fprintf(fout,"\n");
  49. }
  50. void copy_ec(__int64 *p)
  51. {
  52. int i,t;
  53. for(i=0,t=0;i<STABLE;i++){
  54. if(htable[i]!=-(__int64)1){
  55. if(cr[GET_CORN(htable[i])]!=-1){
  56. p[t++]=htable[i];
  57. }
  58. }
  59. }
  60. }
  61. void dump_ec(__int64 htable[])
  62. {
  63. int i;
  64. fout = fopen("dump.txt","w");
  65. for(i=0;i<STABLE;i++){
  66. if(htable[i]!=-(__int64)1){
  67. if(cr[GET_CORN(htable[i])]!=-1){
  68. dump(htable[i]);
  69. }
  70. }
  71. }
  72. fclose(fout);
  73. }
  74. void init()
  75. {
  76. memset(htable,-1,sizeof(htable));
  77. // memset(htable2,-1,sizeof(htable2));
  78. }
  79. int hash(SET s)
  80. {
  81. return (int)(s%STABLE);
  82. }
  83. int add_hash(__int64 htable[],__int64 key, bool eq)
  84. {
  85. int v=hash(key);
  86. __int64 ev;
  87. ev=ECVALUE(key);
  88. if(hc>=STABLE){
  89. fprintf(stderr,"out of hash table range\n");
  90. exit(-1);
  91. }
  92. do{
  93. if(htable[v]==-(__int64)1){
  94. if(eq){
  95. htable[v]=ev;nec++;
  96. }else{
  97. htable[v]=key;
  98. ec++;
  99. }
  100. hc++;
  101. return v;
  102. }else if(htable[v]!=key&&htable[v]!=ev){
  103. v=(v+WALK)%STABLE;
  104. }else{
  105. if(eq){
  106. assert(htable[v]==ev);
  107. }else{
  108. assert(htable[v]==key);
  109. }
  110. return v;
  111. }
  112. }while(1);
  113. }
  114. int query_hash_entry(__int64 htable[],__int64 key)///return index to hash table
  115. {
  116. __int64 ev=ECVALUE(key);
  117. int v=hash(key);
  118. do{
  119. if(htable[v]==-(__int64)1)return v;
  120. if(htable[v]==key||htable[v]==ev)
  121. return v;
  122. v=(v+WALK)%STABLE;
  123. }while(1);
  124. }
  125. void init_neighbour()
  126. {
  127. int i,j;
  128. for(i=0;i<N;i++){
  129. for(j=0;j<N;j++){
  130. SET s=EMPTY_SET;
  131. ADD_INDEX(s,INDEX(i,j));
  132. if(i>0&&j>0){
  133. ADD_INDEX(s,INDEX(i-1,j-1));
  134. }
  135. if(i>0){
  136. ADD_INDEX(s,INDEX(i-1,j));
  137. }
  138. if(j>0){
  139. ADD_INDEX(s,INDEX(i,j-1));
  140. }
  141. if(i>0&&j<N-1){
  142. ADD_INDEX(s,INDEX(i-1,j+1));
  143. }
  144. if(j<N-1){
  145. ADD_INDEX(s,INDEX(i,j+1));
  146. }
  147. if(i<N-1&&j>0){
  148. ADD_INDEX(s,INDEX(i+1,j-1));
  149. }
  150. if(i<N-1){
  151. ADD_INDEX(s,INDEX(i+1,j));
  152. }
  153. if(i<N-1&&j<N-1){
  154. ADD_INDEX(s,INDEX(i+1,j+1));
  155. }
  156. nghb[INDEX(i,j)]=s;
  157. }
  158. }
  159. }
  160. #if 0
  161. void visit(__int64 neighb)
  162. {
  163. int i;
  164. int e=query_hash_entry(htable,neighb);
  165. if(htable[e]==neighb){
  166. int ee=query_hash_entry(htable2,neighb);
  167. if(htable2[ee]==-1){
  168. htable2[ee]=neighb;
  169. lec++;
  170. for(i=0;i<BITS;i++){
  171. if(TEST_BIT(neighb,i)==0){
  172. __int64 newneighb=neighb;
  173. newneighb|=nghb[i];
  174. visit(newneighb);
  175. }
  176. }
  177. }
  178. }else{
  179. for(i=0;i<BITS;i++){
  180. if(TEST_BIT(neighb,i)==0){
  181. __int64 newneighb=neighb;
  182. newneighb|=nghb[i];
  183. int e2=query_hash_entry(htable,newneighb);
  184. if(htable[e2]==newneighb){
  185. visit(newneighb);
  186. break;
  187. }
  188. }
  189. }
  190. }
  191. }
  192. #endif
  193. int query(__int64 neighb)
  194. {
  195. int e=query_hash_entry(htable,neighb);
  196. if(htable[e]!=-1)
  197. return e;
  198. int i;
  199. for(i=0;i<BITS;i++){
  200. if(TEST_BIT(neighb,i)==0){
  201. __int64 newneighb=neighb;
  202. newneighb|=nghb[i];
  203. int r=query(newneighb);
  204. if(htable[r]==newneighb)
  205. break;
  206. }
  207. }
  208. if(i<BITS){///find any status is newneighb
  209. return add_hash(htable,neighb,true);
  210. }else{
  211. return add_hash(htable,neighb,false);
  212. }
  213. }
  214. int cmpll(const void *p,const void *q)
  215. {
  216. const __int64 *lp=(const __int64 *)p;
  217. const __int64 *lq=(const __int64 *)q;
  218. if(*lp==*lq)return 0;
  219. if(*lp<*lq)return -1;
  220. return 1;
  221. }
  222. int main(int argc, char* argv[])
  223. {
  224. int i,j;
  225. init();
  226. init_neighbour();
  227. int s=query((__int64)0);
  228. if(htable[s]==(__int64)0){
  229. printf("First fail\n");
  230. }else{
  231. printf("First successful\n");
  232. }
  233. printf("Total table size %d\n",hc);
  234. printf("Total eq stat found %d\n",ec);
  235. printf("Total neq stat found %d\n",nec);
  236. #if 0
  237. for(i=0;i<BITS;i++){
  238. __int64 r=nghb[i];
  239. printf("%d set={ ",i);
  240. for(j=0;j<BITS;j++){
  241. if(!TEST_BIT(r,j)){
  242. __int64 newneighb=r;
  243. newneighb|=nghb[j];
  244. int u=query_hash_entry(htable,newneighb);
  245. if(htable[u]==newneighb){
  246. printf("%d ",j);
  247. }
  248. }
  249. }
  250. printf("}\n");
  251. }
  252. #endif
  253. return 0;
  254. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-16 21:25:29 | 显示全部楼层
  1. void init()
  2. {
  3. memset(htable,-1,sizeof(htable));
  4. // memset(htable2,-1,sizeof(htable2));
  5. }
复制代码
需要修改
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-21 09:08:06 | 显示全部楼层
下载了一个Microsoft Visual C++ Toolkit 2003,可以编译long long了,运行时间确实很长
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-21 09:21:02 | 显示全部楼层
First fail Total table size 31816105 Total eq stat found 5732950 Total neq stat found 26083155 Total lec stat found 1869201
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-10-21 14:32:19 | 显示全部楼层
21楼 Timer 3.01 Copyright (c) 2002-2003 Igor Pavlov 2003-07-10 First fail Total table size 31816105 Total eq stat found 5732950 Total neq stat found 26083155 Kernel Time = 0.639 = 00:00:00.639 = 1% User Time = 45.240 = 00:00:45.240 = 98% Process Time = 45.879 = 00:00:45.879 = 99% Global Time = 45.911 = 00:00:45.911 = 100%
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 11:06 , Processed in 0.032464 second(s), 17 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表