繁体   English   中英

循环浏览大型2D阵列的每个组合

[英]Loop through every combination of a large 2D Array

在我的程序中,我有一个二维对象数组,例如:

Component[,] layout = new Component[19,16];

关于组件可以有3种可能。

0 - Empty
1 - Cell
2 - Vent

我需要以编程方式为此二维数组生成可能的排列,然后通过一个方法运行它,然后生成下一个排列。

我需要生成所有可能的排列,而不必两次获得相同的排列。

我将使用嵌套的for循环,但是这需要彼此嵌套304个循环,而我宁愿不这样做。

目前,我正在使用以下内容:

for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                Component comp;
                int rand = rng.Next(0, 3);

                switch (rand)
                {
                    case 1:
                        comp = Component.Cell;
                        break;
                    case 2:
                        comp = Component.Vent;
                        break;
                    default:
                        comp = null;
                        break;
                }

                Components[i, j] = comp;
            }
        }

(rng是RNGCryptoServiceProvider的自定义处理程序)

该代码仅生成随机排列,但无法检查该排列是否之前已生成,因此我不希望存储所有先前使用的排列的列表。

有什么合理的方法可以做到这一点吗?

编辑:查看评论后,根据该程序的预期用途,我认为遗传算法实际上是进行此操作的最佳方法。

我会考虑一种遗传算法,因为搜索所有可能选项的整个空间是不可行的。

基本方法是:

  • 随机选择一个开始状态(在执行操作时)
  • 生成X个子状态,这些状态对起始状态的影响很小。 扰动只是父状态的很小变化。 例如随机更改少量单元格
  • 从这组儿童中选出“最佳”
  • 重复

当您发现代代相传的改进低于某个阈值时,通常会停下来。

该算法当然依赖于具有“最佳度”的数值来对每个孩子以及每个孩子进行比较。

使用此算法执行搜索通常非常快。 但是您必须记住,您正在做的所有事情就是找到局部最大值,即靠近起始解决方案的局部最佳解决方案。 因此,通常您会使用不同的起始解决方案一次又一次地运行计算。

就像降落在丘陵景观中的任意点,然后只向上走一样。 您最终会到达山顶,而且通常很快就会到达山顶-但它可能不是整个山脉的最高峰。

但是,如果您对“最佳状态”的度量在所有可能状态的空间中的位置没有合理地平稳变化,则此方法将无效。 想象一下一个杂乱的,锯齿状的景观,垂直壁上有悬崖,少量移动可能不会产生接近的“最佳”价值。

您的2D数组19by16也可以表示为长度为19x16 = 304的1D数组,因此,如果我正确理解,您需要生成例如长度为304的字符串,其中单个字符的所有可能值均为0或1或2即可生成此简单字符您可以确定不会两次得到相同的结果。 生成简单的任务以将其填充到2D数组后

暂无
暂无

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

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