Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 如何使用谷歌或工具解决流量游戏?_Algorithm_Or Tools - Fatal编程技术网

Algorithm 如何使用谷歌或工具解决流量游戏?

Algorithm 如何使用谷歌或工具解决流量游戏?,algorithm,or-tools,Algorithm,Or Tools,我试着用谷歌或其他工具制作流游戏的解算器 我为角点制定了一些规则,使其仅包含角点管道,但除此之外,我不知道如何使管道彼此连接,也不知道如何告诉模型使管道彼此连接 几段 pipe_types = { 0: " ", 1: "-", 2: "|", 3: "┗" , 4: "┛" , 5: "┓", 6: "┏", 7: "●" } mo

我试着用谷歌或其他工具制作流游戏的解算器

我为角点制定了一些规则,使其仅包含角点管道,但除此之外,我不知道如何使管道彼此连接,也不知道如何告诉模型使管道彼此连接

几段

pipe_types = {
0: " ",
1: "-",
2: "|",
3: "┗" ,
4: "┛" ,
5: "┓",
6: "┏",
7: "●" 
}
model = cp_model.CpModel()
filled_map = [[0,0,0,0],
             [0,0,7,0],
             [0,0,0,0],
             [0,7,0,0]]

mesh_size = int(np.sqrt(len(np.array(filled_map).flatten())))

target_map = [[model.NewIntVar(1, 6, 'column: %i' % i) for i in range(mesh_size)] for j in range(mesh_size)]

flow_map = init_map(model, target_map, filled_map)

for i in range(len(flow_map)):
    for j in range(len(flow_map[0])):
        
        # check if top or bottom side
        if (i == 0) or (i == len(flow_map)-1):
            model.Add(flow_map[i][j] != 2)
        
        # check if left or right side
        if (j == 0) or (j == len(flow_map[0])-1):
            model.Add(flow_map[i][j] != 1)
        
        # left up corner
        if (i == 0) & (j == 0):
            model.Add(flow_map[i][j] != 3)
            model.Add(flow_map[i][j] != 4)
            model.Add(flow_map[i][j] != 5)
        
        
        # right up corner
        if (i == 0) & (j == len(flow_map[0])-1):
            model.Add(flow_map[i][j] != 3)
            model.Add(flow_map[i][j] != 4)
            model.Add(flow_map[i][j] != 6)
        
        
        # left bottom corner
        if (i == len(flow_map)-1) & (j == 0):
            model.Add(flow_map[i][j] != 4)
            model.Add(flow_map[i][j] != 5)
            model.Add(flow_map[i][j] != 6)
        
        
        # right bottom corner
        if (i == len(flow_map)-1) & (j == len(flow_map[0])-1):
            model.Add(flow_map[i][j] != 3)
            model.Add(flow_map[i][j] != 5)
            model.Add(flow_map[i][j] != 6)
# Solving
status = solver.Solve(model)

res = []
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
    for i in range(len(flow_map)):
        for j in range(len(flow_map[0])):
            res.append(solver.Value(flow_map[i][j]))
            print(solver.Value(flow_map[i][j]), end=" ")
        print()
这将导致网格中心出现水平管道。稍后,我将不得不想出如何添加颜色等等

有没有关于如何在计算机或工具上进行此操作的指针

编辑1:

根据David Eisenstat的回答,我可以找到解决方案。根据约翰克的答案将这个解决方案可视化,我得到了这个结果

我可以从google或tools获得路径吗

编辑2:

利用哈密顿路径 我可以生成一些正确的路径


但感觉很奇怪,因为或工具已经计算了路径,我必须重新计算路径。从生成的路径未显示所有可能的组合。如果我能从工具中选择路径,我认为这将是我最大的兴趣。

最好的方法可能是使用。该约束采用一个有向图,其中每个弧都用一个文字标记,并且要求标记为true的弧形成一个子图,其中每个节点的进出次数为1,并且最多有一个循环不是自循环。通过强制从端点到端点的圆弧,我们可以使用此约束类型来要求从起点到端点有一条路径

文档有点糟糕,所以这里有一个工作代码示例。我将把绘图部分留给你

import collections
from ortools.sat.python import cp_model


def validate_board_and_count_colors(board):
    assert isinstance(board, list)
    assert all(isinstance(row, list) for row in board)
    assert len(set(map(len, board))) == 1
    colors = collections.Counter(square for row in board for square in row)
    del colors[0]
    assert all(count == 2 for count in colors.values())
    num_colors = len(colors)
    assert set(colors.keys()) == set(range(1, num_colors + 1))
    return num_colors


def main(board):
    num_colors = validate_board_and_count_colors(board)
    model = cp_model.CpModel()
    solution = [
        [square or model.NewIntVar(1, num_colors, "") for (j, square) in enumerate(row)]
        for (i, row) in enumerate(board)
    ]
    true = model.NewBoolVar("")
    model.AddBoolOr([true])
    for color in range(1, num_colors + 1):
        endpoints = []
        arcs = []
        for i, row in enumerate(board):
            for j, square in enumerate(row):
                if square == color:
                    endpoints.append((i, j))
                else:
                    arcs.append(((i, j), (i, j)))
                if i < len(board) - 1:
                    arcs.append(((i, j), (i + 1, j)))
                if j < len(row) - 1:
                    arcs.append(((i, j), (i, j + 1)))
        (i1, j1), (i2, j2) = endpoints
        k1 = i1 * len(row) + j1
        k2 = i2 * len(row) + j2
        arc_variables = [(k2, k1, true)]
        for (i1, j1), (i2, j2) in arcs:
            k1 = i1 * len(row) + j1
            k2 = i2 * len(row) + j2
            edge = model.NewBoolVar("")
            if k1 == k2:
                model.Add(solution[i1][j1] != color).OnlyEnforceIf(edge)
                arc_variables.append((k1, k1, edge))
            else:
                model.Add(solution[i1][j1] == color).OnlyEnforceIf(edge)
                model.Add(solution[i2][j2] == color).OnlyEnforceIf(edge)
                forward = model.NewBoolVar("")
                backward = model.NewBoolVar("")
                model.AddBoolOr([edge, forward.Not()])
                model.AddBoolOr([edge, backward.Not()])
                model.AddBoolOr([edge.Not(), forward, backward])
                model.AddBoolOr([forward.Not(), backward.Not()])
                arc_variables.append((k1, k2, forward))
                arc_variables.append((k2, k1, backward))
        model.AddCircuit(arc_variables)
    solver = cp_model.CpSolver()
    status = solver.Solve(model)
    if status == cp_model.OPTIMAL:
        for row in solution:
            print("".join(str(solver.Value(x)) for x in row))


if __name__ == "__main__":
    main(
        [
            [1, 0, 0, 2, 3],
            [0, 0, 0, 4, 0],
            [0, 0, 4, 0, 0],
            [0, 2, 3, 0, 5],
            [0, 1, 5, 0, 0],
        ]
    )
导入集合
从ortools.sat.python导入cp_模型
def验证板和计数板颜色(板):
断言isinstance(板、列表)
断言全部(板中行的isinstance(行,列表))
断言len(set(map(len,board))==1
颜色=集合。计数器(方格对应方格对应方格对应方格)
del颜色[0]
断言全部(colors.values()中的count=2)
num_colors=len(颜色)
断言集(colors.keys())==set(范围(1,num_colors+1))
返回num_颜色
def主板:
num\u colors=验证\u板\u和\u计数\u颜色(板)
model=cp_model.CpModel()
解决方案=[
枚举(行)中(j,square)的[square或model.NewIntVar(1,num_colors,”)]
用于枚举(板)中的(i,行)
]
true=model.NewBoolVar(“”)
model.AddBoolOr([true])
对于范围内的颜色(1,num_colors+1):
端点=[]
弧=[]
对于i,枚举中的行(板):
对于j,枚举中的平方(行):
如果正方形==颜色:
endpoints.append((i,j))
其他:
附加弧(((i,j),(i,j)))
如果i
由于我没有使用计算机或工具的经验,这里有一种方法

  • 初始电路板由端点的数字表示,每种颜色一个数字。这个想法有点像
  • 电路板上的每个其他单元将获得一个零值或一个数字。这个数字应该正好等于它的两个邻居
  • 初始端点的颜色应正好有一个相邻点
从z3导入解算器、求和、整型、If和或sat
def plot_解决方案:
将matplotlib.pyplot作为plt导入
ax=plt.gca()
颜色=plt.cm.tab10.colors
对于范围内的i(M):
对于范围(N)内的j:
如果板[i][j]!=0:
最大散射(j,i,s=500,color=colors[board[i][j]]
如果S[i][j]!=0:
对于范围内的k(M):
对于范围(N)中的l:
如果abs(k-i)+abs(l-j)==1和S[i][j]==S[k][l]:
轴图([j,l],[i,k],颜色=颜色[S[i][j]],lw=15)
ax.set_ylim(M-0.5,-0.5)
ax.set_xlim(-0.5,N-0.5)
ax.set_方面(“相等”)
ax.设置颜色(“黑色”)
ax.set_yticks([i+0.5表示范围内的i(M-1)],minor=True)
ax.set_xticks([j+0.5表示范围内的j(N-1)],次要=真)
ax.grid(b=True,哪个='minor',color='white')
ax.set_xticks([])
ax.set_-yticks([])
ax.tick_参数(axis='both',which='both',length=0)
plt.show()
董事会=[[1,0,0,2,3],
[[1, 2, 2, 2, 3],
 [1, 2, 4, 4, 3],
 [1, 2, 4, 3, 3],
 [1, 2, 3, 3, 5],
 [1, 1, 5, 5, 5]]