php Peg Puzzle解算器超时

如何解决php Peg Puzzle解算器超时

第一次来这里。 我正在使用递归开发Peg Puzzle php求解器。对于小型和简单的开发板,我得到了预期的结果(脚本正确解决了难题),但是对于大型和完整的开发板​​(即,除了一个插槽之外的所有插槽),我得到了php超时。我需要使其与具有以下布局的7x7板一起使用:
x x 1 1 1 x x
x x 1 1 1 x x
1 1 1 1 1 1 1
1 1 1 0 1 1 1
1 1 1 1 1 1 1
x x 1 1 1 x x
x x 1 1 1 x x
\'x \'不可用的情况下,\'1 \'是带有钉子的插槽,\'0 \'是一个空闲插槽。 该板由7x7阵列(阵列的阵列)表示。我一次遍历一个键,进行以下检查: 此键的值是否为'1 \'? 如果是,则以下键的值也为'1 \'还是以下键'0 \'吗? (这意味着要钉住,并且有一个空间可以移动第一个)。 如果是,那么我将创建电路板的副本并应用这些更改,然后将其重新发送给功能。 如果没有,我朝另一个方向检查(当前检查顺序为:右,左,上,下)。 当脚本无法从该位置找到有效路径时,递归结束。 然后,我进行检查以查看是否只剩下一个钉子(这意味着该板已解决),或者是否还有钉子(这意味着该板尚未解决)。在后者中,应丢弃整个路径。 我将复制并粘贴我的代码,但是由于仍然有些混乱,我更愿意对其进行解释。 我尝试了Rodolphe Courtier的算法(在这里),结果相同。 提前致谢! 编辑:好的,到目前为止,使DFS非递归并没有太大帮助(仍然涉及很多步骤)。因此,现在我正在考虑检查板上的模式,这些模式首先会产生无法解决的难题,如果是这种情况,我会指示脚本不要一开始就遍历它。和以前一样,将发表我的发现。     

解决方法

        我以前用c ++和c#编写过此内容。我可以告诉你7x7阵列不是最好的。将标准深度优先搜索算法和板表示形式视为位板。我可能会在c中发布完整的解决方案,但如果您愿意,可以在其他板上发布。 另外,鉴于该解决方案需要深度优先搜索,因此您确实无法绕过递归。我的第一次尝试做了类似您正在做的事情,但是很慢。位板实施仅需几秒钟即可完成,而不是几分钟。 编辑: 这是我对三角形三角形的15钉板的解决方案。起始板上的所有钉子都位于适当位置,除了三角形的顶部,胜出的解决方案定义为最后一个钉子位于顶部。除了需要重新定义表中可用的动作和合法的动作外,该算法对您的工作方式应相同。 基本说明:董事会安排如下:
        p1
      p2  p3
    p4  p5  p6
  p7  p8  p9  pa
pb  pc  pd  pe  pf
每个位置都映射到16位int上的一位。电路板从p1以外的所有位开始。 “移动”是三位的三元组。例如,(p1,p2,p4)是可能的移动。如果将p1,p2位置1并将p4清零,或者将p2,p4设为1并将p1清零,则移动为“合法”。这里有所有动作的查找表,以及合法动作的定义。 为了进行深度优先搜索,我们需要: 结束状态(一点点:我通过将其定义为仅p1来“欺骗”,这是微不足道的) 进行和撤消移动(将当前板与候选移动进行异或运算,这同样是微不足道的) 生成一组候选移动(再次,一些二进制异或和和运算。唯一复杂的部分,如果需要的话,我可以稍后详细说明...) 代码:
#include <vector>
#include <iostream>
using namespace std;

typedef short state_t;

struct Move {
short move;
const char * desc;
};
typedef Move move_t;

struct Options {
short moves[4];
int size;
};

// name the bits
# define P1 1
# define P2 1 << 1
# define P3 1 << 2
# define P4 1 << 3
# define P5 1 << 4
# define P6 1 << 5
# define P7 1 << 6
# define P8 1 << 7
# define P9 1 << 8
# define P10 1 << 9
# define P11 1 << 10
# define P12 1 << 11
# define P13 1 << 12
# define P14 1 << 13 
# define P15 1 << 14

// not valid location
# define P16 1 << 15

// move triplets
Options options[15] = {
{{P1|P2|P4,P1|P3|P6},2},{{P2|P4|P7,P2|P5|P9},{{P3|P5|P8,P3|P6|P10},{{P1|P2|P4,P4|P7|P11,P4|P5|P6,P4|P8|P13},4},{{P5|P8|P12,P5|P9|P14},{{P1|P3|P6,P6|P9|P13,P6|P10|P15},{{P7|P4|P2,P7|P8|P9},{{P8|P5|P3,P8|P9|P10},{{P9|P8|P7,P9|P5|P2},{{P10|P6|P3,P10|P9|P8},{{P11|P7|P4,P11|P12|P13},{{P12|P8|P5,P12|P13|P14},{{P13|P12|P11,P13|P14|P15,P13|P8|P4,P13|P9|P6},{{P14|P9|P5,P14|P13|P12},{{P15|P10|P6,P15|P14|P13},2}
};

// legal moves
Options legal[15] = {
{{P1|P2,P1|P3},{{P2|P4,P2|P5},{{P3|P5,P3|P6},{{P4|P2,P4|P7,P4|P5,P4|P8},{{P5|P8,P5|P9},{{P6|P3,P6|P5,P6|P9,P6|P10},{{P7|P4,P7|P8},{{P8|P5,P8|P9},{{P9|P8,P9|P5},{{P10|P6,P10|P9},{{P11|P7,P11|P12},{{P12|P8,P12|P13},{{P13|P12,P13|P14,P13|P8,P13|P9},{{P14|P9,P14|P13},{{P15|P10,P15|P14},2}
};

// for printing solution
struct OptionDesc {
const char* name[4];
int size;
};
OptionDesc desc[15] = {
{{\"p1 => p4\",\"p1 => p6\"},{{\"p2 => p7\",\"p2 => p9\"},{{\"p3 => p8\",\"p3 => p10\"},{{\"p4 => p1\",\"p4 => p11\",\"p4 => p6\",\"p4 => p13\"},{{\"p5 => p12\",\"p5 => p14\"},{{\"p6 => p1\",\"p6 => p4\",\"p6 => p13\",\"p6 => p15\"},{{\"p7 => p2\",\"p7 => p9\"},{{\"p8 => p3\",\"p8 => p10\"},{{\"p9 => p7\",\"p9 => p2\"},{{\"p10 => p3\",\"p10 => p8\"},{{\"p11 => p4\",\"p11 => p13\"},{{\"p12 => p5\",\"p12 => p14\"},{{\"p13 => p11\",\"p13 => p15\",\"p13 => p4\",\"p13 => p6\"},{{\"p14 => p5\",\"p14 => p12\"},{{\"p15 => p6\",\"p15 => p13\"},2}
};

int LEGAL_COUNT = sizeof (legal) / sizeof (Options);

state_t START = P2|P3|P4|P5|P6|P7|P8|P9|P10|P11|P12|P13|P14|P15;

// make move: just xor
inline void make_move(state_t& s,move_t m) 
{
s ^= m.move;
}

// undo move: just xor
inline void unmake_move (state_t& s,move_t m)
{
s ^= m.move;
}

// define end state as peg in top position
inline bool end_state (state_t s)
{
return (s ^ START) == (START|P1);
}

// generates moves from table of legal moves,and table of all possible move options
inline void generate_moves(state_t s,vector<move_t>& moves) 
{
for (int i = 0; i < LEGAL_COUNT; i++) {
    for (int j = 0; j < legal[i].size; j++) {
        short L = legal[i].moves[j];
        short M = L ^ options[i].moves[j];
        if ((s & L) == L && (s & M) == 0) {
            move_t m;
            m.move = options[i].moves[j];
            m.desc = desc[i].name[j];
            moves.push_back(m);
        }
    }
}
}

// basic depth first search:
bool dfs (state_t& s,int& count)
{
bool found = false;

if (end_state(s)) {
    count++;
    return true;
}

vector<move_t> moves;
generate_moves(s,moves);

for (vector<move_t>::iterator it = moves.begin();
    it != moves.end(); it++) {
        make_move (s,*it);
        found = dfs(s,count);
        unmake_move(s,*it);
        if (found && 0) {
            cout << it->desc << endl;
            return true;
        }
}
return false;
}

void init(state_t& s)
{
s = START;
}

int main(int argc,char* argv[])
{
state_t s;
int count = 0;
init(s);
bool solved = dfs (s,count);
//cout << \"solved = \" << solved << endl;
cout << \"solutions = \" << count << endl;
char c;
cin >> c;
return 0;
}
    ,根据您的描述,我怀疑主要的慢点是a)递归b)大量复制董事会。如果您可以将其放入循环而不是使用递归,则可能会有所帮助。如果可以使用一块或几块板子(例如,每条潜在路径一块板子,通过引用该功能将其传递),那也可能会有所帮助。 您的运行时间将根据木板的大小和钉子的数量成倍增加;您要做的是使其尽可能缓慢地增加。 例如,假设您有一块20x20的木板,除了1个斑点外,其他所有木板都满了。 (20 ^ 2-1)399钉。这些钉子中的每个钉子都可能在其他398个钉子中进行迭代以找到解决方案:这意味着您的递归循环迭代20x20x20x20次,每次制作一块新的400钉板。那是很多循环,那是很多板子! 根据您链接的代码,我立即看到的唯一优化是让板一次只能找出一个动作,尝试该动作并查看其动作,而不是计算每个阶段的所有动作。不过,这是线性优化,不是指数优化;它可能会在一定程度上有所帮助,但不会有太大帮助。 (例如,代替进行n ^ 2计算来找出每一步,董事会将平均进行(n ^ 2)/ 2-仍然为O(n ^ 2)。 另外,getMoves函数本身非常慢-在我看来,它可以被重写为更快,特别是如果被调用16万次。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-