[
  {
    "path": "README.md",
    "content": "\n### 基于dijkstra算法的AGV路径规划 AGV path planning based on dijkstra algorithm\n\n#### dijkstra算法 dijkstra algorithm\n\n经典Dijkstra算法是一种贪心算法，根据路径长度递增次序找到最短路径，通常用于解决单源最短路的问题。Dijkstra算法的基本思想是：首先根据原有路径图，初始化源点到与其相邻节点的距离，选出与源点最短距离的节点进行松弛操作，即比较判断若经过该点，是否能找到比源点到其他点更短的距离，若有更短的距离则更新原有距离，直至遍历初始图中的所有节点。Dijkstra算法可找出源点到初始图中所有点的最短距离，任意最短路径的子路径仍为最短路径。\n     \nDijkstra算法是以标号为基础的标签算法，设一个有向图由n个点和e条弧组成，该有向图可表示为G=(V,E)，V表示节点集，E表示弧集，可用C(A,B)来表示A和B点之间弧的长度，若在该有向图中A点和B点间不可达，则可用无穷大或者远大于C(A,B)数量级的整数来表示。可设一个数组DIST(X)来表示节点X与原点v0之间的距离，S和V-S分别表示目前暂确定找到最短路径节点的集合与未确定最短路径节点集合，初始时S仅包含v0源点，算法结束时S应包含所有节点。\n\nDijkstra算法的步骤如下：\n**Step.1** 初始化，将源点v0加入集合S，并做标记；\n**Step.2** 在V-S中寻找与v0有连接的点，并选择距离最短的点i做标记，将其加入S中；\n**Step.3** 将i作为新的起始点，在V-S中寻找与i直接可达且距离最短的点j，若DIST[j]>DIST[i]+C(i,j)，意味着目前来看从源点到j的距离经过i点比直接从v0到j要短，所以将DIST[j]更新为DIST[i]+C(i,j)，并将j点加入S集合；\n**Step.4** 重复Step.2、Step.3步骤n-1次，可找到源点v0到所有点的最短距离；\n**Step.5** 依次输出源点、中间点、目标点连成路径。\n\nThe classic Dijkstra algorithm is a greedy algorithm that finds the shortest path according to the ascending order of path length. It is usually used to solve the single-source shortest path problem. The basic idea of ​​the Dijkstra algorithm is: first, according to the original path graph, initialize the distance from the source point to its adjacent nodes, select the node with the shortest distance to the source point for relaxation operation, that is, compare and judge whether a shorter distance can be found than the distance from the source point to other points if passing through this point. If there is a shorter distance, update the original distance until all nodes in the initial graph are traversed. The Dijkstra algorithm can find the shortest distance from the source point to all points in the initial graph, and the subpath of any shortest path is still the shortest path.\nDijkstra algorithm is a labeling algorithm based on labeling. Suppose a directed graph consists of n points and e arcs. The directed graph can be represented as G=(V,E), where V represents the node set and E represents the arc set. C(A,B) can be used to represent the length of the arc between points A and B. If points A and B are unreachable in the directed graph, they can be represented by an integer of infinity or much larger than C(A,B). An array DIST(X) can be set to represent the distance between node X and the origin v0. S and V-S represent the set of nodes that have been temporarily determined to find the shortest path and the set of nodes that have not been determined to find the shortest path. Initially, S only contains the source point v0. When the algorithm ends, S should contain all nodes.\n\nThe steps of Dijkstra algorithm are as follows:\n**Step.1** Initialize, add source point v0 to set S and mark it;\n**Step.2** Find points connected to v0 in V-S, select point i with the shortest distance to mark it, and add it to S;\n**Step.3** Take i as the new starting point, find point j in V-S that is directly reachable from i and has the shortest distance. If DIST[j]>DIST[i]+C(i,j), it means that the distance from the source point to j through point i is shorter than that from v0 to j directly, so update DIST[j] to DIST[i]+C(i,j), and add point j to set S;\n**Step.4** Repeat Step.2 and Step.3 n-1 times to find the shortest distance from source point v0 to all points;\n**Step.5** Output the source point, intermediate point, and target point in sequence to form a path.\n\n#### 项目背景 Project Background\n\n现代化仓库中AGV（自动避障小车）的使用颇多，本项目为AGV的路径规划和多车避让提供一种较为初级的解决方案。\n\n首先，基于实际仓库运作场景，本文做出以下假设：\n* 通常情况下，AGV的数量恒定，不考虑AGV突然增加或减少的情况；\n* AGV运行速度恒定，不考虑停下加速或减速停下的时段，且空载和负载状态下AGV运行速度相等；\n* 订单是否优先级由上位机确定，分配给AGV执行；\n* 每台AGV一次只能执行一个任务，且一个任务能且仅能被一台AGV执行一次；\n* 本文设定AGV系统采用集中式控制方式，各AGV的任务来源于上位机，且每台AGV均与上位机通信，AGV之间没有信息交互。\n\n根据作业类型，AGV系统可由三个模块组成：任务生成模块、任务分配模块和路径规划模块。仓库不断接收到新订单，则任务生成模块不断生成新任务，不断进行着任务分配和路径规划。AGV系统的整体作业流程如下：\n\n\n1. **任务生成**：上位机接收仓库订单，将其转化为AGV可执行的任务，生成一个任务集合，任务完成后则从任务集合中删除该任务。\n2. **任务分配**：此模板的目标是确保每个任务圆满完成的情况下总的任务完成最短。在一定的任务序列优化规则下，结合任务的优先级，给AGV传达任务指令。另外，任务分配还需要考虑各个AGV的均衡运作，避免部分AGV由于任务过于繁重而降低寿命。由于AGV的运行是时间连续性的，所以任务分配模块给AGV传达的是一个任务序列，AGV按照此序列依次执行任务。\n3. **路径规划**：在实际情况中，一个仓库往往有多台AGV，路径规划模块最重要的是为每一台AGV合理规划路径，当AGV接收到特定任务时，首先需要为其初步规划行走路线，根据其他AGV的行走状况进行必要的调整，避免出现碰撞或死锁情况。\n\nAGV (Automatic Obstacle Avoidance Vehicle) is widely used in modern warehouses. This project provides a relatively basic solution for AGV path planning and multi-vehicle avoidance.\n\nFirst, based on the actual warehouse operation scenario, this article makes the following assumptions:\n* Under normal circumstances, the number of AGVs is constant, and the sudden increase or decrease of AGVs is not considered;\n* The running speed of AGV is constant, and the period of stopping to accelerate or decelerate is not considered, and the running speed of AGV is equal under no-load and load conditions;\n* The priority of the order is determined by the host computer and assigned to the AGV for execution;\n* Each AGV can only perform one task at a time, and a task can and can only be performed once by one AGV;\n* This article assumes that the AGV system adopts a centralized control method, and the tasks of each AGV come from the host computer, and each AGV communicates with the host computer, and there is no information exchange between AGVs.\n\nAccording to the type of operation, the AGV system can be composed of three modules: task generation module, task allocation module and path planning module. As the warehouse continuously receives new orders, the task generation module continuously generates new tasks, continuously performs task allocation and path planning. The overall operation process of the AGV system is as follows:\n\n1. **Task generation**: The host computer receives warehouse orders, converts them into tasks executable by AGV, generates a task set, and deletes the task from the task set after the task is completed.\n2. **Task allocation**: The goal of this template is to ensure that the total task completion time is the shortest when each task is completed satisfactorily. Under certain task sequence optimization rules, combined with the priority of the task, the task instructions are conveyed to the AGV. In addition, task allocation also needs to consider the balanced operation of each AGV to avoid the life of some AGVs being reduced due to excessively heavy tasks. Since the operation of AGV is time-continuous, the task allocation module conveys a task sequence to the AGV, and the AGV executes tasks in sequence according to this sequence.\n3. **Path planning**: In actual situations, a warehouse often has multiple AGVs. The most important thing about the path planning module is to reasonably plan the path for each AGV. When the AGV receives a specific task, it first needs to preliminarily plan its walking route, and make necessary adjustments based on the walking conditions of other AGVs to avoid collisions or deadlocks.\n\n#### 类设计 Class design\n\n##### Map类 \n\n* 从文件中导入仓库位置点与路径\n\n* 可以使用图存放仓库位置点与路径集\n\n* 可以使用dijkstra算法解出最优路径路径，并根据转弯数由多到少进行排序。\n\n##### AGV类\n\n* 可根据输入参数求解各个AGV自己的路径集\n\n* 从中根据快速、防碰撞两个原则进行路径的选择\n\n* 实时移动\n\n##### Map \n\n* Import warehouse location points and paths from files\n\n* Use graphs to store warehouse location points and path sets\n\n* Use dijkstra algorithm to solve the optimal path and sort them from most to least according to the number of turns.\n\n##### AGV \n\n* Solve the path set of each AGV according to the input parameters\n\n* Select the path based on the two principles of fast and anti-collision\n\n* Real-time movement\n\n#### 工程实现 #### Engineering implementation\n\n[代码库/Code](\nhttps://github.com/Superone77/AGV_dijkstra/tree/master/code)\n\n\n"
  },
  {
    "path": "code/AGV.cpp",
    "content": "#include\"AGV.h\"\r\n#include<iostream>\r\n\r\nusing namespace std;\r\n\r\n\r\nAGV::~AGV()\r\n{\r\n\tdelete agvMap;\r\n\tagvMap=NULL;\r\n}\r\n\r\nvoid\r\nAGV::move() //移动\r\n{\r\n\tif (checkFree)\r\n\t\tnext_point = this_point;\r\n\telse \r\n\t{\r\n\t\tthis_point = next_point;\r\n\t\tif (i != 1)\r\n\t\t{\r\n\t\t\tnext_point = agv_path.front();\r\n\t\t\tagv_path.pop(); \r\n\t\t}\r\n\t\t\r\n\t}\r\n\tif (agv_path.empty())\r\n\t{\r\n\t\tif (i == 1)\r\n\t\t{\r\n\t\t\tcheckFree = true;\r\n\t\t\ti = 0;\r\n\t\t\tdelete agvMap;\r\n\t\t\tagvMap = NULL;\r\n\t\t}\r\n\t\ti++;\r\n\t}\r\n\r\n\t    \r\n\tcout << this_point << endl;\r\n}\r\n\r\nvoid\r\nAGV::setStart(bool (&isFull)[N][N],int t) \r\n{\r\n\tcout << \"setStart\" << endl;\r\n\tcheckFree = false;  \r\n\tnext_point = agvMap->startpoint;\r\n\tint time = t;\r\n\tfor (int k = 0; i < agvMap->paths.size(); i++) //通过换路径防止碰撞\r\n\t{\r\n\t\tfor (int j = 0; j < agvMap->paths[k].path.size(); j++)\r\n\t\t{\r\n\t\t\tif (isFull[agvMap->paths[k].path[j]][time])\r\n\t\t\t{\r\n\t\t\t\tcout << \"已被占用的节点\" << agvMap->paths[k].path[j] << \"---\" << \"第\" << time << \"s\" << endl;\r\n\t\t\t\twhile (!agv_path.empty())\r\n\t\t\t\t{\r\n\t\t\t\t\tagv_path.pop();\r\n\t\t\t\t\tcout << \"删除尾节点\" << endl;\r\n\t\t\t\t}\r\n\t\t\t\tfor (j=j-1;j >=0; j--)\r\n\t\t\t\t{\r\n\t\t\t\t\tcout << \"释放占用的节点\" << endl;\r\n\t\t\t\t\tisFull[agvMap->paths[k].path[j]][time] = false;\r\n\t\t\t\t\ttime--;\r\n\t\t\t\t}\r\n\t\t\t\tif (j == 0)\r\n\t\t\t\t\ttime = t;\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tagv_path.push(agvMap->paths[k].path[j]);\r\n\t\t\tcout << \"成功占用节点：\" << agvMap->paths[k].path[j] << \"---\" << \"第\" << time << \"s\" << endl;\r\n\t\t\tisFull[agvMap->paths[k].path[j]][time] = true;\r\n\t\t\ttime++;\r\n\t\t}\r\n\r\n\t\tif (!agv_path.empty())\r\n\t\t\tbreak;\r\n\t}\r\n\tif (agv_path.empty()) //通过碰撞前停止防止碰撞\r\n\t{\r\n\t\tfor (int j = 0; j < agvMap->paths[0].path.size(); j++)\r\n\t\t{\r\n\t\t\tif (isFull[agvMap->paths[0].path[j]][time])\r\n\t\t\t{\r\n\t\t\t\tj--;\r\n\t\t\t\tagv_path.push(agvMap->paths[0].path[j]);\r\n\t\t\t\tisFull[agvMap->paths[0].path[j]][time] = true;\r\n\t\t\t\ttime++;\r\n\t\t\t\tcontinue;\r\n\t\t\t\t\r\n\r\n\t\t\t}\r\n\t\t\tagv_path.push(agvMap->paths[0].path[j]);\r\n\t\t\tisFull[agvMap->paths[0].path[j]][time] = true;\r\n\t\t\ttime++;\r\n\t\t}\r\n\t}\r\n\ti = 0;\r\n\t\t\r\n\r\n\t\r\n}"
  },
  {
    "path": "code/AGV.h",
    "content": "#include\"Map.h\"\r\n#include<queue>\r\n\r\nusing namespace std;\r\n\r\nclass AGV\r\n{\r\npublic:\r\n\t~AGV();\r\n\tMap *agvMap;\r\n\tint next_point;\r\n\tint this_point;\r\n\tbool checkFree = true;//是否有任务给AGV\r\n\tqueue<int> agv_path;\r\n\tint i=0;\r\npublic:\r\n\tvoid setStart(bool (&isFull)[N][N] ,int t); //将路径输入AGV\r\n\tvoid move(); //移动\r\n};"
  },
  {
    "path": "code/Map.cpp",
    "content": "#include\"AGV.h\"\r\n#include\"Map.h\"\r\n\r\n\r\n\r\n\r\nMap::Map()\r\n{\r\n\r\n}\r\n\r\nint Map::G1[N][N];\r\n\r\nMap::~Map()\r\n{\r\n\t\r\n}\r\n\r\nvoid Map::addEdge(int from, int to, int cost, vector<Edge> G[N])//双向赋值，1-2和2-1是一样的cost\r\n{\r\n\tEdge e(to, cost);\r\n\tG[from].push_back(e);\r\n\r\n\tEdge e1(from, cost);\r\n\tG[to].push_back(e1);\r\n}\r\n\r\nvoid Map::solve()\r\n{\r\n\tint sta, finall;\r\n\tcout << \"请输入起点:\" << endl;\r\n\tcin >> sta;\r\n\tstartpoint = sta;\r\n\tcout << \"请输入终点:\" << endl;\r\n\tcin >> finall;\r\n\r\n\tbuild();\r\n\tdijkstra(sta, G);\r\n\r\n\tint unsigned i, j;\r\n\r\n\r\n\t//vector<Ans> paths;\r\n\tAns ans;\r\n\tmemset(vis, false, sizeof(vis));\r\n\r\n\tdfs(sta, finall, ans, paths, sta);\r\n\r\n\tcout << endl << sta << \"到\" << finall << \"的所有最短路径：\" << endl;\r\n\tint tsize;\r\n\ttsize = paths.size();\r\n\tint *t = new int[tsize];\r\n\tfor (i = 0; i < paths.size(); i++)\r\n\t{\r\n\t\t*(t + i) = 0;\r\n\t\tcout << sta << \" - \";\r\n\t\tfor (j = 0; j < paths[i].path.size(); j++)\r\n\t\t{\r\n\t\t\tcout << paths[i].path[j] << \" - \";\r\n\t\t\tif (j > 1 && abs(paths[i].path[j] - paths[i].path[j - 2]) != 22 && abs(paths[i].path[j] - paths[i].path[j - 2]) != 2)\r\n\t\t\t{\r\n\t\t\t\t*(t + i) += 1;\r\n\t\t\t}\r\n\t\t\telse if (j == 1 && abs(paths[i].path[j] - sta) != 22 && abs(paths[i].path[j] - sta) != 2)\r\n\t\t\t{\r\n\t\t\t\t*(t + i) += 1;\r\n\t\t\t}\r\n\t\t}\r\n\t\tcout << \"---cost：\" << paths[i].cost << \"   \" << \"转弯数：\" << *(t + i) << endl;\r\n\t}\r\n\tcout << \"     \" << endl;\r\n\tcout << \"     \" << endl;\r\n\tturnMin = 1000;\r\n\tfor (i = 0; i < paths.size(); i++) //寻找最小转弯数\r\n\t{\r\n\t\tif (turnMin > *(t + i))\r\n\t\t{\r\n\t\t\tturnMin = *(t + i);\r\n\t\t}\r\n\t}\r\n\tcout << \"最优路径为：  \" << endl;\r\n\tfor (i = 0; i < paths.size(); i++) //输出最小转弯数所对应的路径\r\n\t{\r\n\t\tif (*(t + i) == turnMin)\r\n\t\t{\r\n\t\t\tcout << sta << \" - \";\r\n\t\t\tfor (j = 0; j < paths[i].path.size(); j++)\r\n\t\t\t{\r\n\t\t\t\tcout << paths[i].path[j] << \" - \";\r\n\t\t\t}\r\n\t\t\tcout << \"---cost：\" << paths[i].cost << \"   \" << \"转弯数：\" << turnMin << endl;\r\n\t\t}\r\n\t}\r\n\tcout << \"     \" << endl;\r\n\tcout << \"次优路径为：  \" << endl;\r\n\tfor (i = 0; i < paths.size(); i++) //输出次小转弯数所对应的路径\r\n\t{\r\n\t\tif (*(t + i) == turnMin + 1)\r\n\t\t{\r\n\t\t\tcout << sta << \" -\";\r\n\t\t\tfor (j = 0; j < paths[i].path.size(); j++)\r\n\t\t\t{\r\n\t\t\t\tcout << paths[i].path[j] << \" - \";\r\n\t\t\t}\r\n\t\t\tcout << \"---cost：\" << paths[i].cost << \"   \" << \"转弯数：\" << turnMin + 1 << endl;\r\n\t\t}\r\n\t}\r\n}\r\nvoid Map::build()\r\n{\r\n\tint i;\r\n\tifstream fin;\r\n\tfin.open(\"data.txt\");\r\n\tfin >> nV;//输入顶点数\r\n\tfin >> nE;//输入边数\r\n\r\n\t// 输入图，初始化为所有两点距离为INF\r\n\tfor (i = 0; i < nV; i++)\r\n\t{\r\n\t\tfor (int j = i; j < nV; j++)\r\n\t\t{\r\n\t\t\tG1[i][j] = G1[j][i] = INF;\r\n\t\t}\r\n\t}\r\n\tint from, to, cost;//输入两点间距离\r\n\tfor (i = 0; i < nE; i++)\r\n\t{\r\n\t\tfin >> from >> to >> cost;\r\n\r\n\t\taddEdge(from, to, cost, G);\r\n\t\tG1[from][to] = G1[to][from] = cost;\r\n\t}\r\n\tfin.close();\r\n}\r\n\r\nvoid Map::dijkstra(int s, vector<Edge> G[N]) // 求最短路径\r\n{\r\n\tfill(dist, dist + nV + 1, INF);\r\n\tpriority_queue<P, vector<P>, greater<P> > q;\r\n\tdist[s] = 0;\r\n\tq.push(P(0, s));\r\n\twhile (!q.empty())\r\n\t{\r\n\t\tP p = q.top();   //从尚未使用的顶点中找到一个距离最小的顶点\r\n\t\tq.pop();\r\n\t\tint v = p.second;\r\n\t\tif (dist[v] < p.first)\r\n\t\t\tcontinue;\r\n\t\tfor (int unsigned i = 0; i < G[v].size(); i++)\r\n\t\t{\r\n\t\t\tEdge &e = G[v][i];\r\n\t\t\tint dis = dist[v] + e.cost;\r\n\t\t\tif (dist[e.to] > dis)\r\n\t\t\t{\r\n\t\t\t\tdist[e.to] = dist[v] + e.cost;\r\n\t\t\t\tq.push(P(dist[e.to], e.to));\r\n\t\t\t\tG4[v].push_back(e);\r\n\t\t\t}\r\n\t\t\telse if (dist[e.to] == dis)\r\n\t\t\t{\r\n\t\t\t\tG4[v].push_back(e);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\nvoid Map::dfs(int s, int t, Ans &A, vector< Ans > &paths, int start)\r\n{\r\n\tif (s == t)\r\n\t{\r\n\t\tA.start = start;\r\n\t\tA.getCost();\r\n\t\tpaths.push_back(A);\r\n\t}\r\n\r\n\tfor (int unsigned i = 0; i < G4[s].size(); i++)\r\n\t{\r\n\t\tint u = G4[s][i].to;\r\n\t\tif (!vis[u])\r\n\t\t{\r\n\t\t\tvis[u] = true;\r\n\t\t\tA.path.push_back(u);\r\n\t\t\tdfs(u, t, A, paths, start);\r\n\t\t\tA.path.pop_back();\r\n\t\t\tvis[u] = false;\r\n\t\t}\r\n\t}\r\n}"
  },
  {
    "path": "code/Map.h",
    "content": "#pragma once\r\n#include <iostream>\r\n#include \"string\"\r\n#include \"fstream\"\r\n#include \"vector\"\r\n#include \"queue\"\r\n#include \"sstream\"\r\n#include \"set\"\r\n#include \"string.h\"\r\n#include \"math.h\"\r\n#include <functional>\r\n\r\nusing namespace std;\r\n\r\n#define INF 200000000\r\n#define N 100\r\n\r\n\r\n\r\nclass Map\r\n{\r\npublic:\r\n\tstruct  Edge\r\n\t{\r\n\t\tint to;          // 边终止节点\r\n\t\tint cost;        // 花费\r\n\r\n\t\tEdge(int to1, int cost1)\r\n\t\t{\r\n\t\t\tto = to1;\r\n\t\t\tcost = cost1;\r\n\t\t}\r\n\t};\r\n\tstruct Ans\r\n\t{\r\n\t\tvector<int> path;\r\n\t\tint cost;\r\n\t\tint start;\r\n\r\n\t\tvoid getCost()\r\n\t\t{\r\n\t\t\tcost = G1[start][path[0]];\r\n\t\t\tfor (int unsigned i = 0; i < path.size() - 1; i++)\r\n\t\t\t{\r\n\t\t\t\tcost += G1[path[i]][path[i + 1]];\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\tint startpoint;\r\n\tint turnMin;\r\n\tvector<Ans> paths;\r\n\tstatic int G1[N][N];                // 图的邻接矩阵形式\r\n\tint dist[N];                 // 从源点出发的最短距离\r\n\tint nV;                      // 顶点数\r\n\tint nE;\r\n\tvector<Edge> G[N];\r\n\tvector<Edge> G4[N];\r\n\tbool vis[N];\r\n\ttypedef pair<int, int> P;    // first是最短距离，second是顶点编号\r\npublic:\r\n\tMap();\r\n\t~Map();\r\n\tvoid solve();\r\n\tvoid build();\r\n\tvoid dijkstra(int s, vector<Edge> G[N]);            // 求最短路径\r\n\tvoid addEdge(int from, int to, int cost, vector<Edge> G[N]);//双向赋值，1-2和2-1是一样的cost\r\n\tvoid dfs(int s, int t, Ans &A, vector< Ans > &paths, int start);\r\n\r\n};"
  },
  {
    "path": "code/data.txt",
    "content": "88\r\n157\r\n1 2 1\r\n2 3 1\r\n3 4 1\r\n4 5 1\r\n5 6 1\r\n6 7 1 \r\n7 8 1\r\n8 9 1\r\n9 10 1\r\n10 11 1\r\n12 13 1 \r\n13 14 1\r\n14 15 1\r\n15 16 1\r\n16 17 1\r\n17 18 1\r\n18 19 1\r\n19 20 1\r\n20 21 1\r\n21 22 1\r\n23 24 1\r\n24 25 1\r\n25 26 1\r\n26 27 1\r\n27 28 1\r\n28 29 1\r\n29 30 1\r\n30 31 1\r\n31 32 1\r\n32 33 1\r\n34 35 1\r\n35 36 1\r\n36 37 1\r\n37 38 1\r\n38 39 1\r\n39 40 1\r\n40 41 1\r\n41 42 1 \r\n42 43 1\r\n43 44 1\r\n45 46 1\r\n46 47 1\r\n47 48 1\r\n48 49 1\r\n49 50 1\r\n50 51 1\r\n51 52 1\r\n52 53 1\r\n53 54 1\r\n54 55 1\r\n56 57 1\r\n57 58 1\r\n58 59 1\r\n59 60 1\r\n60 61 1\r\n61 62 1\r\n62 63 1\r\n63 64 1\r\n64 65 1\r\n65 66 1\r\n67 68 1\r\n68 69 1\r\n69 70 1\r\n70 71 1\r\n71 72 1\r\n72 73 1\r\n73 74 1\r\n74 75 1\r\n75 76 1\r\n76 77 1\r\n78 79 1\r\n79 80 1\r\n80 81 1\r\n81 82 1\r\n82 83 1\r\n83 84 1\r\n84 85 1\r\n85 86 1\r\n86 87 1\r\n87 88 1\r\n1 12 1\r\n12 23 1\r\n23 34 1\r\n34 45 1\r\n45 56 1\r\n56 67 1\r\n67 78 1\r\n2 13 1\r\n13 24 1\r\n24 35 1\r\n35 46 1\r\n46 57 1\r\n57 68 1\r\n68 79 1\r\n3 14 1 \r\n14 25 1\r\n25 36 1\r\n36 47 1\r\n47 58 1\r\n58 69 1\r\n69 80 1\r\n4 15 1\r\n15 26 1\r\n26 37 1\r\n37 48 1\r\n48 59 1\r\n59 70 1\r\n70 81 1\r\n5 16 1\r\n16 27 1\r\n27 38 1\r\n38 49 1\r\n49 60 1\r\n60 71 1\r\n71 82 1\r\n6 17 1\r\n17 28 1\r\n28 39 1\r\n39 50 1\r\n50 61 1\r\n61 72 1 \r\n72 84 1\r\n7 18 1\r\n18 29 1\r\n29 40 1\r\n40 51 1\r\n51 62 1\r\n62 73 1\r\n73 84 1\r\n8 19 1\r\n19 30 1\r\n30 41 1\r\n41 52 1\r\n52 63 1\r\n63 74 1\r\n74 85 1\r\n9 20 1\r\n20 31 1\r\n31 42 1\r\n42 53 1\r\n53 64 1\r\n64 75 1\r\n75 86 1\r\n10 21 1\r\n21 32 1\r\n32 43 1\r\n43 54 1\r\n54 65 1\r\n65 76 1\r\n76 87 1\r\n11 22 1\r\n22 33 1\r\n33 44 1\r\n44 55 1\r\n55 66 1\r\n66 77 1\r\n77 88 1\r\n\r\n\r\n\r\n\r\n\r\n\r\n"
  },
  {
    "path": "code/main.cpp",
    "content": "#include <iostream>\r\n#include \"string\"\r\n#include \"fstream\"\r\n#include \"vector\"\r\n#include \"queue\"\r\n#include \"sstream\"\r\n#include \"set\"\r\n#include \"string.h\"\r\n#include \"math.h\"\r\n#include <functional>\r\n#include \"AGV.h\"\r\n#include\"Map.h\"\r\n\r\nusing namespace std;\r\n\r\nint main()\r\n{\r\n\tbool isFull[N][N]; // 前一个参数是点，后一个参数是时间，表示什么时间什么点被占据\r\n\tAGV agv1;\r\n\tAGV agv2;\r\n\tint time = 1; //初始化时间\r\n\tMap map;\r\n\tfor (int i = 0; i < N; i++)\r\n\t{\r\n\t\tfor (int j = 0; j < N; j++)\r\n\t\t{\r\n\t\t\tisFull[i][j] = false; \r\n\t\t}\r\n\t}\r\n\t\r\n\twhile (true)\r\n\t{\r\n\t\tcout << \"第\" << time << \"秒：\" << endl;\r\n\t\tif (agv1.checkFree)\r\n\t\t{\r\n\t\t\tint n;\r\n\t\t\tcout << \"是有否任务给1号车（0.是，1.否）\" << endl;\r\n\t\t\tcin >> n;\r\n\t\t\tif (n == 0)\r\n\t\t\t{\r\n\t\t\t\t\r\n\t\t\t\tagv1.agvMap = new Map;\r\n\t\t\t\tagv1.agvMap->solve();\r\n\t\t\t\tagv1.setStart(isFull,time);\r\n\t\t\t\t\r\n\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (agv2.checkFree)\r\n\t\t{\r\n\t\t\tint n;\r\n\t\t\tcout << \"是否有任务给2号车（0.是，1.否）\" << endl;\r\n\t\t\tcin >> n;\r\n\t\t\tif (n == 0)\r\n\t\t\t{\r\n\t\t\t\t\r\n\t\t\t\tagv2.agvMap = new Map;\r\n\t\t\t\tagv2.agvMap->solve();\r\n\t\t\t\tagv2.setStart(isFull,time);\r\n\t\t\t}\r\n\r\n\t\t}\r\n\t\tcout << \"A:\";\r\n\t\tagv1.move();\r\n\t\tcout << \"B:\";\r\n\t\tagv2.move();\r\n\t\t\r\n\t\ttime++;\r\n\t\tif (time == 10)\r\n\t\t\texit(0);\r\n\t}\r\n\r\n\r\n\r\n\treturn 0;\r\n}\r\n\r\n"
  }
]