简体   繁体   English

井字游戏的阶乘数组

[英]factorial array for tic tac toe

I am currently trying to teach myself C++ and programming in general. 我目前正在尝试自学一般的C ++和编程。 So as a beginner project i'm making a genetic algorithm that creates an optimal AI for a Tic-Tac-Toe game. 因此,作为一个初学者项目,我正在制定一种遗传算法,为井字游戏创建最佳的AI。 I am not enrolled in any programming classes so this is not homework. 我没有参加任何编程课程,所以这不是家庭作业。 I'm just really interested in AI. 我对AI真的很感兴趣。

So i am trying to create a multidimensional array of a factorial, in my case 9! 因此,我正在尝试创建阶乘的多维数组,在我的案例9中! . For example if you made one of 3! 例如,如果您获得3分之一! it would be array[3][6] = { {1, 2, 3}, {1, 3, 2}, {2, 3, 1}, {2, 1, 3}, {3, 2, 1}, {3, 1, 2}}. 它将是array [3] [6] = {{1,2,3},{1,3,2},{2,3,1},{2,1,3},{3,2,1 },{3,1,2}}。 Basically 3! 基本上是3个! or 3*2*1 would be the amount of ways you could arrange 3 numbers in order. 或3 * 2 * 1就是您可以按顺序排列3个数字的方式。

I think that the solution should be simple yet im stuck trying to find out how to come up with a simple solution. 我认为该解决方案应该很简单,但是却一直试图找出一种简单的解决方案。 I have tried to swap them, tried to shift them right, increment ect.. the methods that work are the obvious ones and i don't know how to code them. 我试图交换它们,试图向右移动它们,递增等等。有效的方法是显而易见的方法,我不知道如何编写它们。

So if you know how to solve it that's great. 因此,如果您知道如何解决它,那就太好了。 If you can give a coding format that's better . 如果可以提供更好的编码格式。 Any help is appreciated. 任何帮助表示赞赏。

Also i'm coding this in c++. 我也用C ++编写代码。

You can use next_permutation function of STL 您可以使用STL的next_permutation函数

http://www.cplusplus.com/reference/algorithm/next_permutation/ http://www.cplusplus.com/reference/algorithm/next_permutation/

I actually wrote an algorithm for this by hand once. 我实际上为此手工编写了一次算法。 Here it is: 这里是:

bool incr(int z[NUM_INDICES]){
    int a=NUM_INDICES-1;
    for(int i=NUM_INDICES-2;i>=0;i--)
      if(z[i]>z[i+1]) a--;
      else break;
    if(a==0) return false;
    int b=2147483647,c;
    for(int i=a;i<=NUM_INDICES-1;i++)
      if(z[i]>z[a-1]&&z[i]-z[a-1]<b){
        b=z[i]-z[a-1];
        c=i;
      }
    int temp=z[a-1]; z[a-1]=z[c]; z[c]=temp;
    qsort(z+a,NUM_INDICES-a,sizeof(int),comp);
    return true;
}

This is the increment function (ie you have an array like [3,2,4,1], you pass it to this, and it modifies it to [3,4,1,2]). 这是增量函数(即,您有一个像[3,2,4,1]的数组,将其传递给它,然后将其修改为[3,4,1,2])。 It works off the fact that if the last d elements of the array are in descending order, then the next array (in "alphabetical" order) should satisfy the following conditions: 1) the last d+1 elements are a permutation among themselves; 它消除了以下事实:如果数组的最后d个元素按降序排列,则下一个数组(按“字母”顺序)应满足以下条件:1)最后的d + 1个元素是它们之间的排列; 2) the d+1 -th to last element is the next highest element in the last d+1 elements; 2)倒数第d + 1个元素是最后d + 1个元素中的倒数第二元素; 3) the last d elements should be in ascending order. 3)最后d个元素应按升序排列。 You can see this intuitively when you have something like [2,5,3, 8,7,6,4,1]: d = 5 in this case; 当您有[2,5,3,8,7,6,4,1]之类的东西时,您可以直观地看到: d = 5在这种情况下; the 3 turns into the next highest of the last d+1 = 6 elements; 3变成最后d + 1 = 6个元素的下一个最高位; and the last d = 5 are arranged in ascending order, so it becomes [2,5,4, 1,3,6,7,8]. 并且最后的d = 5以升序排列,因此它变为[2,5,4,1,3,6,7,8]。

The first loop basically determines d . 第一循环基本上确定d It loops over the array backwards, comparing consecutive elements, to determine the number of elements at the end that are in descending order. 它向后循环遍历数组,比较连续的元素,以确定末尾按降序排列的元素数。 At the end of the loop, a becomes the first element that is in the descending order sequence. 在循环结束时, a成为按降序顺序排列的第一个元素。 If a==0 , then the whole array is in descending order and nothing more can be done. 如果a==0 ,则整个数组按降序排列,无法执行其他操作。

The next loop determines what the d+1 -th-to-last element should be. 下一个循环确定第d + 1个元素应该是什么。 We specified that it should be the next highest element in the last d+1 elements, so this loop determines what that is. 我们指定它应该是最后d + 1个元素中的倒数第二元素,因此此循环确定它是什么。 (Note that z[a-1] is the d+1 -th-to-last element.) By the end of that loop, b contains the lowest z[i]-z[a-1] that is positive; (请注意,z [a-1]是第d + 1个元素。)在该循环结束时, b包含最低的z[i]-z[a-1]为正; that is, z[i] should be greater than z[a-1] , but as low as possible (so that z[a-1] becomes the next highest element). 也就是说, z[i]应该大于z[a-1] ,但应尽可能小(以使z[a-1]成为次高的元素)。 c contains the index of the corresponding element. c包含相应元素的索引。 We discard b because we only need the index. 我们丢弃b是因为我们只需要索引。

The next three lines swap z[a-1] and z[c] , so that the d+1 -th-to-last element gets the element next in line, and the other element ( z[c] ) gets to keep z[a-1] . 接下来的三行交换z[a-1]z[c] ,以便第d + 1个元素到最后一个元素排成行的下一个元素,而另一个元素( z[c] )保持不变z[a-1] Finally, we sort the last d elements using qsort ( comp must be declared elsewhere; see C++ documentation on qsort ). 最后,我们使用qsort对最后的d个元素进行排序(必须在其他地方声明comp ;请参阅qsort上的C ++文档)。

If you want a hand crafted function for generating all permutations, you can use 如果您想要一个用于生成所有排列的手工函数,则可以使用

#include <cstdio>
#define REP(i,n) FOR(i,0,n)
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define GI ({int t;scanf("%d",&t);t;})

int a[22], n;

void swap(int & a, int & b) {
    int t = a; a = b; b = t;
}

void perm(int pos) {
    if(pos==n) {
        REP(i,n) printf("%d ",a[i]); printf("\n");
        return;
    }
    FOR(i,pos,n) {
        swap(a[i],a[pos]);
        perm(pos+1);
        swap(a[pos],a[i]);
    }
    return;
}

int main (int argc, char const* argv[]) {

    n = GI;
    REP(i,n) a[i] = GI;
    perm(0);

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM