Arrays 如何从二维数组构建图形?
我正在努力学习图形结构和算法。从概念上讲,我理解DFS、BFS,并且我可以通过一个图来实现它们,但是传统上图是如何组成的呢 通常,我将它们视为以边为指针的节点列表、边与其连接的节点的列表,或者是一个二维矩阵,其中两个arr[node_a][node_b]的交点是边的权重 当涉及到用输入构建它时,我不知道从哪里开始 例如,当提供一个二维网格(在线pacman问题)时,您将如何构建一个图,其中p是源节点,而-,是树中的节点Arrays 如何从二维数组构建图形?,arrays,algorithm,graph,Arrays,Algorithm,Graph,我正在努力学习图形结构和算法。从概念上讲,我理解DFS、BFS,并且我可以通过一个图来实现它们,但是传统上图是如何组成的呢 通常,我将它们视为以边为指针的节点列表、边与其连接的节点的列表,或者是一个二维矩阵,其中两个arr[node_a][node_b]的交点是边的权重 当涉及到用输入构建它时,我不知道从哪里开始 例如,当提供一个二维网格(在线pacman问题)时,您将如何构建一个图,其中p是源节点,而-,是树中的节点 %%%%%%%%%%%%%%%%%%%% %--------------%-
%%%%%%%%%%%%%%%%%%%%
%--------------%---%
%-%%-%%-%%-%%-%%-%-%
%--------P-------%-%
%%%%%%%%%%%%%%%%%%-%
%.-----------------%
%%%%%%%%%%%%%%%%%%%%
或者,如果提供了邻接列表,您将如何构建它
我知道这可能是一个大问题,因为问题相当复杂。欢迎链接到文档!从入门级开始,我一直很难找到任何图形。图形通常使用以下两种数据结构之一进行存储:
您必须将任何要表示为图形的输入(例如,解析它)转换为上述数据结构之一。为此,我编写了此javascript,它将矩阵(数组的数组)转换为非加权图形。它开始在4个方向(上/下/右/左)上导航,而不必在已经到达的地方行走 然后,它将使用DFS查找最短路径
const wall = 0
const flat = 1
const target = 9
// no diagonals
const possibleMoves = [
[-1, 0], // nord
[0, +1],
[+1, 0], // sud
[0, -1],
]
function pathFinder(map) {
const gridW = map[0].length
const gridH = map.length
const start = buildNode([0, 0], map)
const tree = buildTreeMap(start, map, [start])
const path = navigateTree(tree)
console.log(path.map(_ => _.point));
return path.length
// Depth-first search (DFS)
function navigateTree(node) {
const dfp = (acc, _) => {
if (_.value === target) {
acc.push(_)
return acc
}
const targetInMyChildren = _.children.reduce(dfp, [])
if (targetInMyChildren.length > 0) {
targetInMyChildren.unshift(_)
return targetInMyChildren
}
return acc
}
return node.children.reduce(dfp, [])
}
function buildTreeMap(node, map2d, visited) {
const [x, y] = node.point
node.children = possibleMoves
.map((([incx, incy]) => [x + incx, y + incy]))
.filter(([nx, ny]) => {
/**
* REMOVE
* + out of grid
* + walls
* + already visited points
*/
if (nx < 0 || nx >= gridW
|| ny < 0 || ny >= gridH
|| map2d[ny][nx] === wall) {
return false
}
return visited.findIndex(vis => vis.point[0] === nx && vis.point[1] === ny) === -1
})
.map(_ => {
const newNode = buildNode(_, map2d)
visited.push(newNode)
return newNode
})
node.children.forEach(_ => buildTreeMap(_, map2d, visited))
return node
}
}
function buildNode(point, map) {
const value = map[point[1]][point[0]]
return {
point,
value,
children: []
}
}
const stepsCount = pathFinder([
[1, 1, 1, 1],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 1, 1, 1],
[0, 1, 1, 1],
[9, 0, 1, 1],
[1, 1, 1, 1],
[1, 0, 1, 0],
[1, 1, 1, 1]
])
console.log(stepsCount);
const wall=0
常数平坦=1
常数目标=9
//没有对角线
常量可能移动=[
[-1,0],//nord
[0, +1],
[+1,0],//sud
[0, -1],
]
功能探路者(地图){
常量gridW=map[0]。长度
const gridH=map.length
const start=buildNode([0,0],map)
const tree=buildTreeMap(开始,映射,[start])
const path=navigateTree(树)
log(path.map(=>wu.point));
返回路径长度
//深度优先搜索(DFS)
函数navigateTree(节点){
常数dfp=(acc,)=>{
如果(u.value==目标){
加速推力
返回acc
}
const targetInMyChildren=\ u0.children.reduce(dfp,[])
如果(targetInMyChildren.length>0){
targetMyChildren.unshift(41;
返回targetMyChildren
}
返回acc
}
返回node.children.reduce(dfp,[])
}
函数buildTreeMap(节点,map2d,已访问){
常数[x,y]=节点点
node.children=possibleMoves
.map((([incx,incy])=>[x+incx,y+incy]))
.filter(([nx,ny])=>{
/**
*除去
*+电网外
*+墙
*+已访问点
*/
如果(nx<0 | | nx>=gridW
||ny<0 | | ny>=gridH
||map2d[ny][nx]==墙){
返回错误
}
返回已访问的.findIndex(vis=>vis.point[0]==nx&&vis.point[1]==ny)=-1
})
.map(=>{
const newNode=buildNode(\ux,map2d)
已访问。推送(新节点)
返回新节点
})
node.children.forEach(=>buildTreeMap(z,map2d,已访问))
返回节点
}
}
功能构建节点(点、地图){
常量值=映射[点[1]][点[0]]
返回{
指向
价值
儿童:[]
}
}
const stepsunt=探路者([
[1, 1, 1, 1],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 1, 1, 1],
[0, 1, 1, 1],
[9, 0, 1, 1],
[1, 1, 1, 1],
[1, 0, 1, 0],
[1, 1, 1, 1]
])
控制台日志(StepScont);
事实上,如果你得到了这个网格,为什么要制作一个图形?你可以将网格用作隐式图形,对吗?@harold我怎么能这样做?这就是我上面说的。我正在寻找解析部分。创建一个节点和边类。边可以有两个节点(每个端点一个)。节点可以有一组边(连接到的每个节点一个边)。一次解析一个字符的2D输入数组。创建一组节点对象。当您遇到一个“-”时,请检查它是否在哈希集中(例如,您已经为它创建了一个节点),如果没有,请创建一个新的节点对象。然后检查“-”(顶部、底部、左侧、右侧)周围的四个位置,如果看到任何“-”,请创建新的节点对象并将它们连接起来。