C++ 图对策算法
我试图模拟以下游戏: 这场比赛有两名选手参加。假设您有一个带有顶点和边的图。每转一圈都可以删除一条边,如果隔离一个顶点,则会得到一个点,然后可以删除另一个点。你一直玩到没有更多的优势,在这一点上,得分最多的玩家赢得比赛 我用数组表示图形,从另一个程序生成的单独文件中读取,例如:C++ 图对策算法,c++,algorithm,matrix,graph-algorithm,C++,Algorithm,Matrix,Graph Algorithm,我试图模拟以下游戏: 这场比赛有两名选手参加。假设您有一个带有顶点和边的图。每转一圈都可以删除一条边,如果隔离一个顶点,则会得到一个点,然后可以删除另一个点。你一直玩到没有更多的优势,在这一点上,得分最多的玩家赢得比赛 我用数组表示图形,从另一个程序生成的单独文件中读取,例如: 0 1 1 0 1 0 1 1 1 1 0 0 0 1 0 0 玩家1可以用4/0获胜,但玩家2也可以。 对于玩家1,最好的结果是1/3 编辑:“一个玩家如何以4/0获胜?” 正如你所看到的,如果去除中间边缘,第一个玩
0 1 1 0
1 0 1 1
1 1 0 0
0 1 0 0
玩家1可以用4/0获胜,但玩家2也可以。
对于玩家1,最好的结果是1/3
编辑:“一个玩家如何以4/0获胜?”
正如你所看到的,如果去除中间边缘,第一个玩家将得到4分,否则另一个玩家将得到4分
我可以为每个玩家得到最好的结果,但是另一个玩家不会选择他最好的回合。我花了很多时间做实验,但我总是遇到同样的问题
编辑:我想我现在已经很接近解决这个问题了(然后我一直在想),我只需要为每回合保存2分,然后我必须设法做到这一点,以便只接受当前玩家的最高分数。那样的话,我应该可以做到让玩家忽略4/0的移动
编辑:我已经尝试实施这个建议,但不幸的是,我又被卡住了。我要么得到一个太高的奇怪输出,要么函数简单地给了我-2作为答案,但它在其他更大的图上不起作用。我尝试了很多方法来修复它,但就是不起作用。下面的代码是我正在尝试的,不幸的是它也不起作用:
int Matrix::getTurn (bool** array) {
if (edges == 0)
return 0;
for (int i=0; i<edges; i++) {
for (int j=0; j<edges; j++) {
if (array[i][j] == true) {
array[i][j] = false;
array[j][i] = false;
score = getScore (array, i, j);
if (score > 0)
score += getTurn (array);
else score -= getTurn (array);
if (score > maxScore)
maxScore = score;
array[i][j] = true;
array[j][i] = true;
}
}
}
return maxScore;
}
int矩阵::getTurn(布尔**数组){
如果(边==0)
返回0;
对于(int i=0;i maxScore)
maxScore=分数;
数组[i][j]=真;
数组[j][i]=真;
}
}
}
返回maxScore;
}
maxScore和score是类的成员变量。有人能指出哪一部分需要纠正吗
另一次编辑,仍然不起作用,现在我根本看不到错误。它不断输出1,就像它从未改变过maxScore。。。
Takken是剩余的边数,我尝试使用数组的边界,但没有任何区别
int Matrix::berekenZet (bool** array) {
if (takken == 0)
return 0;
int maxScore = 0, score = 0;
for (int i=0; i<takken; i++) {
for (int j=0; j<takken; j++) {
if (array[i][j] == true) {
array[i][j] = false;
array[j][i] = false;
takken -= 1;
score = berekenScore (array, i, j);
if (score > 0)
score += berekenZet (array);
else score -= berekenZet (array);
if (score > maxScore)
maxScore = score;
array[i][j] = true;
array[j][i] = true;
takken += 1;
score = 0;
}
}
}
return maxScore;
}
int矩阵::berekenZet(布尔**数组){
如果(takken==0)
返回0;
int maxScore=0,分数=0;
对于(int i=0;i maxScore)
maxScore=分数;
数组[i][j]=真;
数组[j][i]=真;
塔肯+=1;
得分=0;
}
}
}
返回maxScore;
}
提前感谢。您似乎正在尝试实现某种形式的算法。假设两个玩家都为自己做出了最好的动作,这将为玩家找到可能的最佳得分 <>但是你的代码中有一些奇怪的东西:太多的分数变量,在函数中间无条件地分配给
getScore(graph)
将为轮到的玩家返回尽可能最好的分数(假设两个玩家都在最大化自己的分数),其中“分数”表示该玩家的分数减去另一个玩家的分数。我用的是minimax的变体。这使用了一个事实,即一个玩家的+x分数与另一个玩家的-x分数相同,以避免写东西两次。甚至不需要记录轮到谁了,因为两个玩家可以做出完全相同的动作
int getScore(graph):
if no possible moves:
return 0
maxScore = -infinity
for each possible move:
make the move
score = the score directly obtained by this move
if the player gets another turn:
score += getScore(graph)
else: //opponent turn - subtract opponent's best score from player score
score -= getScore(graph)
maxScore = max(maxScore, score)
undo the move
return maxScore
我想你的意思是“顶点/顶点”而不是“向量”。谢谢,更改了。是的,但我也想知道正确的分数。哦,等等,我看错了问题,对不起。我以为吃最后一道菜的人赢了,但实际上吃最多菜的人赢了。我的错。考虑到邻接矩阵,我不知道两个玩家如何赢得4/0。谢谢,我试过了,但我总是会遇到无法解释的错误。我会稍后再试。当我使用这种方法时,我发现它不会选择最好的打法,而是会找到最好的结果,并以此为基础进行转身。然而,这与我在所有其他方法中遇到的问题是一样的,它将选择4 | 0,这是不正确的…@user2180680它应该工作,并给出-2的结果。如果它给出了错误的结果,那是因为代码中的某个错误。我不知道为什么,但我就是无法让它工作。它可以使用4条边,但如果使用更大的边数,则会失败,或者根本不起作用。最糟糕的是我不知道哪里出了问题。@user2180680好吧,你的代码有很多问题。快速浏览的示例:1。它使用了
边
,其中应使用顶点数(??)。2.如果没有可能的移动,则不检查。3.未初始化maxScore
。4.所有变量都应该是局部变量,而不是全局变量或成员变量。
int getScore(graph):
if no possible moves:
return 0
maxScore = -infinity
for each possible move:
make the move
score = the score directly obtained by this move
if the player gets another turn:
score += getScore(graph)
else: //opponent turn - subtract opponent's best score from player score
score -= getScore(graph)
maxScore = max(maxScore, score)
undo the move
return maxScore