查找选定的Tiles中是否存在有效的Rummikub解决方案

时间:2009-11-05 21:21:31

标签: algorithm

我正在制作一个朗姆酒“游戏”,这样当我制作Mistake时,我就可以轻松地将电路板恢复到以前的状态。

如果存在解决方案以及解决方案是什么,目前需要找出给定数量的磁贴。

示例

选择的元素是 {Red1,Red1,Blue1,Black1,Orange1,Orange1}

一个解决方案就是 {Red1,Blue1,Orange1}和{Red1,Black1,Orange1}

我目前可以确定哪些组和运行是可能的({Red1,Blue1,Black1,Orange1}是一个有效的组,不会出现在有效的解决方案中)。我需要一个可以进行下一步的解决方案,并告诉我哪些组/运行可以一起存在并确保每个磁贴使用一次。如果不存在这样的解决方案,则需要能够报告。解决方案不一定是最优的(即使用最少数量的组/运行),它必须是有效的。

2 个答案:

答案 0 :(得分:3)

为一组给定的瓷砖找到最高得分解决方案是一个棘手的问题。它已经成为许多论文的主题。最新的方法是ILP(整数线性规划)。

基本上,它意味着您定义了一个您希望最大化的函数,并对其进行约束。 例如:

  • 列出所有独特的瓷砖(标准游戏中的53个)
  • 列出所有可能的有效集(1174)

定义:

  • yi =在最佳解决方案中选择tile i的次数
  • sij =表示我在集合j中的更好的瓷砖
  • ti =在表格中找到瓷砖的次数
  • ri =在架子上找到瓷砖的次数

G = y1 + y2 + ... y52 + y53

然后是:

  • sum [xj * sij,j = 1 ... 1174] = ti + yi(i = 1 ... 53)
  • yi< = ri(i = 1 ... 53)
  • 0< = xj< = 2(j = 1 ... 1174)
  • 0< = yi< = 2(i = 1 ... 53)

解决方案将由xj的系数给出(告诉您确切地在解决方案中包含哪些集合)。最大化的功能当然是G.

这种方法可以很快地解决给定的情况(20个图块需要1秒)。

答案 1 :(得分:1)

如果您有一种确定哪些组和运行可能的方法,为什么不修改算法以删除已经使用过的图块,并使函数递归。这是一些伪代码:

array PickTiles(TileArray) {

    GroupsArray = all possible groups/runs;

    foreach Group in GroupsArray {
         newTileArray = TileArray;
         remove Group from newTileArray;

         if(newTileArray.length() == 0) {
               return array(Group);
         }

         result = PickTiles(newTileArray);
         if(result.length() > 0) {
               return result.append(array(Group));
         }
    }

    return array();
}