├── .gitignore ├── MAStar ├── Results │ ├── sim-1.gif │ ├── sim-1.jpg │ ├── sim-2-r29.gif │ └── sim-2-r29.jpg ├── angleDiff.m ├── priority.m ├── selectTopNode_simple.m ├── updateOpen.m ├── readme.md ├── finalOpen.m ├── optimalPath_simple.m ├── optimalPath_1.m ├── collisionsCheck2.m ├── expand.m ├── neighbors8.m ├── initializationMh.m ├── addStallNodes.m ├── MRPP_simple.m ├── neighbors4.m ├── MRPP_1.m ├── createModelAstar.m ├── RUN_MAStar.m ├── selectTopNode_1.m ├── createModel_ctest.m ├── MRPP_2.m ├── createModel_1.m ├── MRPP_3.m └── createModel_2.m ├── models ├── FromExcell │ ├── Book1.xlsx │ ├── createSaveModelExcel.m │ └── createModelFromExcel.m ├── FromMapFile │ ├── aa_random-64-64-10-random-1.mat │ ├── createScenarios.m │ ├── createSaveModelFile.m │ ├── addRobotToModel.m │ ├── createMapFromFile.m │ ├── createModelFromMap.m │ ├── random-64-64-10.map │ └── random-64-64-10-random-1.scen ├── RandomModel │ ├── createSaveModelRandom.m │ └── createModelRand.m └── checkFeasibility.m ├── common ├── nodes2coords.m ├── calSmoothnessByDir.m ├── calCostL.m ├── calDistance.m ├── plotSolution.m ├── nodes2dirs.m ├── calSmoothness.m ├── plotAnimation_1.m ├── modifyPath.m ├── plotAnimation_3.m ├── calCostLinear.m ├── collisionsCheck.m ├── plotAnimation_2.m └── plotModelMulti.m ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | *.asv 2 | MRDStarLite 3 | /MRDStarLite -------------------------------------------------------------------------------- /MAStar/Results/sim-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MortezaHagh/mrpp-matlab/HEAD/MAStar/Results/sim-1.gif -------------------------------------------------------------------------------- /MAStar/Results/sim-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MortezaHagh/mrpp-matlab/HEAD/MAStar/Results/sim-1.jpg -------------------------------------------------------------------------------- /MAStar/Results/sim-2-r29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MortezaHagh/mrpp-matlab/HEAD/MAStar/Results/sim-2-r29.gif -------------------------------------------------------------------------------- /MAStar/Results/sim-2-r29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MortezaHagh/mrpp-matlab/HEAD/MAStar/Results/sim-2-r29.jpg -------------------------------------------------------------------------------- /models/FromExcell/Book1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MortezaHagh/mrpp-matlab/HEAD/models/FromExcell/Book1.xlsx -------------------------------------------------------------------------------- /MAStar/angleDiff.m: -------------------------------------------------------------------------------- 1 | function ad = angleDiff(v, ref_ang) 2 | 3 | ad = mod(((v - ref_ang) + pi), 2*pi) - pi; 4 | 5 | end 6 | -------------------------------------------------------------------------------- /models/FromMapFile/aa_random-64-64-10-random-1.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MortezaHagh/mrpp-matlab/HEAD/models/FromMapFile/aa_random-64-64-10-random-1.mat -------------------------------------------------------------------------------- /common/nodes2coords.m: -------------------------------------------------------------------------------- 1 | function path_coords = nodes2coords(Path, Model) 2 | % return coordinates of nodes 3 | 4 | path_coords = Model.Nodes.cord(:, Path); 5 | path_coords = path_coords'; 6 | 7 | end -------------------------------------------------------------------------------- /common/calSmoothnessByDir.m: -------------------------------------------------------------------------------- 1 | function smoothness = calSmoothnessByDir(sol) 2 | 3 | dn = diff(sol.nodeNumbers); 4 | stall = dn == 0; 5 | 6 | sol.dirs(stall) = []; 7 | 8 | theta = sol.dirs; 9 | dTheta = angdiff(theta); 10 | smoothness = sum(abs(dTheta)); 11 | 12 | end 13 | -------------------------------------------------------------------------------- /common/calCostL.m: -------------------------------------------------------------------------------- 1 | function cost = calCostL(coords) 2 | 3 | xPath = coords(:, 1); 4 | yPath = coords(:, 2); 5 | 6 | dxPath = diff(xPath); 7 | dyPath = diff(yPath); 8 | 9 | % path length 10 | L = sum(sqrt(dxPath .^ 2 + dyPath .^ 2)); 11 | 12 | cost = L; 13 | 14 | end 15 | -------------------------------------------------------------------------------- /common/calDistance.m: -------------------------------------------------------------------------------- 1 | function dist = calcalDistance(x1, y1, x2, y2, type) 2 | 3 | if strcmp(type, 'euclidean') 4 | % euclidean calDistance 5 | dist = sqrt((x1 - x2) ^ 2 + (y1 - y2) ^ 2); 6 | elseif strcmp(type, 'manhattan') 7 | % manhattan calDistance 8 | dist = abs(x1 - x2) + abs(y1 - y2); 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /common/plotSolution.m: -------------------------------------------------------------------------------- 1 | function plotSolution(Sol, Model, Color) 2 | 3 | robotCount = Model.robotCount; 4 | figure(1) 5 | hold on 6 | 7 | for nr = 1:robotCount 8 | plot(Sol(nr).x, Sol(nr).y, 'color', Color(nr, :), 'LineWidth', 1); 9 | plot(Sol(nr).x(2:end - 1), Sol(nr).y(2:end - 1), 'o', 'MarkerFaceColor', Color(nr, :), 'MarkerEdgeColor', Color(nr, :), ... 10 | 'MarkerSize', 3); 11 | end 12 | 13 | end 14 | -------------------------------------------------------------------------------- /MAStar/priority.m: -------------------------------------------------------------------------------- 1 | function sorted_list = priority(Robots, robot_list, Model, nodes) 2 | 3 | h = zeros(numel(robot_list), 1); 4 | j = 1; 5 | 6 | for i = robot_list 7 | xyp = Model.Nodes.cord(:, nodes(i)); 8 | xyt = Model.Nodes.cord(:, Robots(i).targetNode); 9 | h(j) = calDistance(xyp(1), xyp(2), xyt(1), xyt(2), Model.distType); 10 | j = j + 1; 11 | end 12 | 13 | [~, ind] = sort(h); 14 | sorted_list = robot_list(ind); 15 | end 16 | -------------------------------------------------------------------------------- /MAStar/selectTopNode_simple.m: -------------------------------------------------------------------------------- 1 | function openTopInd = selectTopNode_simple(Open, targetNode, dir, nr) 2 | 3 | openTopInd = -1; % 'no path!' 4 | 5 | % no_visit: not_visited_id 6 | no_visit = ~[Open(nr).List.visited]; 7 | 8 | if sum(no_visit) > 0 9 | candids = [[Open(nr).List(no_visit).fCost]; 10 | abs([Open(nr).List(no_visit).dir] - dir); 11 | find(no_visit)]'; 12 | 13 | [~, ind_candids] = sortrows(candids(:, 1:2)); 14 | openTopInd = candids(ind_candids(1), end); 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /models/FromExcell/createSaveModelExcel.m: -------------------------------------------------------------------------------- 1 | clc 2 | clear 3 | close 4 | 5 | % add path 6 | addpath('..\..\common'); 7 | 8 | % settings 9 | Model.distType = 'manhattan'; % euclidean manhattan; 10 | Model.adjType = '4adj'; % '4adj' '8adj' 11 | Model.occLength = 1000; 12 | 13 | % from Excel 14 | Model = createModelFromExcel(Model); 15 | 16 | % % check Feasibility 17 | % isFeasible = checkFeasibility(Model); 18 | % if ~isFeasible 19 | % disp('Not Feasible!') 20 | % end 21 | 22 | % % save Model 23 | % save('Model','Model') 24 | 25 | % Plot 26 | plotModelMulti(Model); 27 | -------------------------------------------------------------------------------- /models/FromMapFile/createScenarios.m: -------------------------------------------------------------------------------- 1 | function scenarios = createScenarios(path) 2 | 3 | % path = 'Berlin_1_256-random-1.scen'; 4 | 5 | fid = fopen(path); 6 | fgetl(fid); 7 | 8 | N = 1000; 9 | 10 | iLine = 1; 11 | scenarios = zeros(N, 4); 12 | tline = fgetl(fid); 13 | 14 | while ischar(tline) 15 | temp = split(tline); 16 | temp = temp(5:8); 17 | temp = str2double(temp)'; 18 | 19 | scenarios(iLine, :) = temp; 20 | tline = fgetl(fid); 21 | iLine = iLine + 1; 22 | end 23 | 24 | fclose(fid); 25 | 26 | end 27 | -------------------------------------------------------------------------------- /common/nodes2dirs.m: -------------------------------------------------------------------------------- 1 | function pathDirs = nodes2dirs(nodeNumbers, Model) 2 | % return direction array of path nodes 3 | 4 | nNodes = numel(nodeNumbers); 5 | pathDirs = zeros(1, nNodes); 6 | 7 | for i = 2:nNodes 8 | node1_xy = Model.Nodes.cord(:, nodeNumbers(i - 1)); 9 | node2_xy = Model.Nodes.cord(:, nodeNumbers(i)); 10 | 11 | dd = node2_xy - node1_xy; 12 | dx = dd(1); 13 | dy = dd(2); 14 | nodeTheta = atan2(dy, dx); 15 | pathDirs(i - 1) = nodeTheta; 16 | end 17 | 18 | pathDirs(end) = pathDirs(end - 1); 19 | 20 | end 21 | -------------------------------------------------------------------------------- /common/calSmoothness.m: -------------------------------------------------------------------------------- 1 | function smoothness = calSmoothness(pathCoords) 2 | 3 | solX = pathCoords(:, 1); 4 | solY = pathCoords(:, 2); 5 | 6 | dx = diff(solX); 7 | dy = diff(solY); 8 | 9 | stall = dx == 0 & dy == 0; 10 | dx(stall) = []; 11 | dy(stall) = []; 12 | solX(stall) = []; 13 | solY(stall) = []; 14 | 15 | if numel(solX) > 2 16 | alpha = zeros(1, length(dx) - 1); 17 | 18 | for i = 1:length(dx) - 1 19 | a = sqrt(dx(i + 1) ^ 2 + dy(i + 1) ^ 2); 20 | b = sqrt(dx(i) ^ 2 + dy(i) ^ 2); 21 | c = (solX(i) - solX(i + 2)) ^ 2 + (solY(i) - solY(i + 2)) ^ 2; 22 | gamma = abs(acos((a ^ 2 + b ^ 2 - c) / (2 * a * b))); 23 | alpha(i) = pi - gamma; 24 | end 25 | 26 | sm = sum(alpha); 27 | smoothness = round(sm, 3); 28 | else 29 | smoothness = 0; 30 | end 31 | 32 | end 33 | -------------------------------------------------------------------------------- /common/plotAnimation_1.m: -------------------------------------------------------------------------------- 1 | function plotAnimation_1(Sol, Model, Color) 2 | % animated points and Paths, in turn. 3 | 4 | robotCount = Model.robotCount; 5 | 6 | i = 1; 7 | flag = true(robotCount, 1); 8 | 9 | while any(flag) 10 | 11 | for nr = 1:robotCount 12 | 13 | if i > numel(Sol(nr).x) 14 | flag(nr) = false; 15 | end 16 | 17 | if flag(nr) 18 | plot(Sol(nr).x(i), Sol(nr).y(i), 'o', 'MarkerFaceColor', Color(nr, :), 'MarkerEdgeColor', Color(nr, :)); 19 | text(Sol(nr).x(i) + 0.1, Sol(nr).y(i) + 0.1, num2str(i), 'Color', Color(nr, :)) 20 | 21 | if i > 1 22 | plot(Sol(nr).x(i - 1:i), Sol(nr).y(i - 1:i), 'Color', Color(nr, :), 'LineWidth', 2); 23 | end 24 | 25 | pause(0.2) 26 | end 27 | 28 | end 29 | 30 | i = i + 1; 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /MAStar/updateOpen.m: -------------------------------------------------------------------------------- 1 | function Open = updateOpen(Open, neighbors) 2 | 3 | % update or extend Open list with the successor nodes 4 | for i = 1:neighbors.count 5 | neighbors_open_common = [Open.List.nodeNumber] == neighbors.List(i).nodeNumber & [Open.List.visited] == 0; 6 | 7 | % if there is a common node in neighbors and Open 8 | if any(neighbors_open_common) 9 | open_ind = find(neighbors_open_common); 10 | 11 | % if fCost of node in exp_array is less than Open -> update node in Open 12 | if neighbors.List(i).fCost < Open.List(open_ind).fCost 13 | Open.List(open_ind) = neighbors.List(i); 14 | end 15 | 16 | % if there is No common node in exp_count and Open 17 | else 18 | % insert neighbor into the Open list 19 | Open.count = Open.count + 1; 20 | Open.List(Open.count) = neighbors.List(i); 21 | end 22 | 23 | end 24 | 25 | end 26 | -------------------------------------------------------------------------------- /MAStar/readme.md: -------------------------------------------------------------------------------- 1 | # MRPP-MH: Multi Robot Path Planning based on Astar - MATLAB 2 | 3 | --------------------------------------------------------- 4 | 5 | ## MRPP_simple 6 | 7 | no cooperation at all: many collisions 8 | no time in Open list 9 | 10 | #### functions 11 | 12 | - selectTopNode_simple 13 | - optimalPath_simple 14 | 15 | --------------------------------------------------------- 16 | 17 | ## MRPP_1 18 | 19 | expand Open list by collision consideration 20 | with time in Open list 21 | stall node is added 22 | 23 | #### functions 24 | 25 | - selectTopNode_1 26 | - optimalPath_1 27 | 28 | --------------------------------------------------------- 29 | 30 | ## MRPP_2 31 | 32 | same as MRPP_1, only difference: 33 | calculates path and update Open for each robot that reaches target 34 | 35 | #### functions 36 | 37 | - selectTopNode_1 38 | - optimalPath_1 39 | 40 | --------------------------------------------------------- 41 | 42 | ## in all 43 | 44 | adding targetNodes to ClosedList 45 | -------------------------------------------------------------------------------- /MAStar/finalOpen.m: -------------------------------------------------------------------------------- 1 | function Open = finalOpen(path) 2 | 3 | N = 10; 4 | path_len = numel(path.nodeNumbers); 5 | first.visited = 1; 6 | first.nodeNumber = path.nodeNumbers(1); 7 | first.pNode = path.nodeNumbers(1); 8 | first.gCost = 0; 9 | first.hCost = 0; 10 | first.dir = 0; 11 | first.time = 0; 12 | Open.List = first; 13 | 14 | for p = 2:path_len 15 | Open.List(p) = first; 16 | Open.List(p).nodeNumber = path.nodeNumbers(p); 17 | Open.List(p).pNode = path.nodeNumbers(p - 1); 18 | Open.List(p).time = p - 1; 19 | end 20 | 21 | Open.List(path_len + 1) = Open.List(p); 22 | Open.List(path_len + 1).pNode = Open.List(path_len + 1).nodeNumber; 23 | Open.List(path_len + 1).time = Open.List(path_len + 1).time + 1; 24 | 25 | for pp = path_len + 2:path_len + N 26 | Open.List(pp) = Open.List(pp - 1); 27 | Open.List(pp).time = Open.List(pp - 1).time + 1; 28 | end 29 | 30 | Open.count = path_len + N; 31 | 32 | end 33 | -------------------------------------------------------------------------------- /MAStar/optimalPath_simple.m: -------------------------------------------------------------------------------- 1 | function path = optimalPath_simple(Model, Open, isPath, nr) 2 | 3 | path_nodes = Model.Robots(nr).startNode * [1, 1]; 4 | parent_ind = 1; 5 | 6 | if isPath(nr) == 1 7 | % starting from the last (target) node 8 | path_nodes(1) = Model.Robots(nr).targetNode; 9 | i = 2; 10 | 11 | % Traverse Open and determine the parent nodes 12 | parent_ind = [Open.List.nodeNumber] == path_nodes(1); 13 | parent_node = Open.List(parent_ind).pNode; 14 | 15 | % going back to start node 16 | while parent_node ~= Model.Robots(nr).startNode 17 | path_nodes(i) = parent_node; 18 | parent_ind = [Open.List.nodeNumber] == parent_node; 19 | parent_node = Open.List(parent_ind).pNode; 20 | i = i + 1; 21 | end 22 | 23 | end 24 | 25 | path.nodeNumbers = [Model.Robots(nr).startNode, flip(path_nodes)]; 26 | path.coords = nodes2coords(path.nodeNumbers, Model); 27 | path.dirs = nodes2dirs(path.nodeNumbers, Model); 28 | 29 | end 30 | -------------------------------------------------------------------------------- /models/FromMapFile/createSaveModelFile.m: -------------------------------------------------------------------------------- 1 | clc 2 | clear 3 | close 4 | 5 | % add path 6 | addpath('..\..\common'); 7 | 8 | % setting 9 | Model.distType = 'manhattan'; % euclidean manhattan; 10 | Model.adjType = '4adj'; % 4adj 8adj 11 | 12 | % 13 | Model.robotCount = 10; 14 | 15 | % create map from file 16 | [Map, Name] = createMapFromFile('random-64-64-10.map'); 17 | 18 | % create Model from map 19 | Model = createModelFromMap(Map, Model); 20 | 21 | % scenario 22 | scene_path = 'random-64-64-10-random-1.scen'; 23 | scenarios = createScenarios(scene_path); 24 | 25 | load('aa_random-64-64-10-random-1'); 26 | scenarios = scenarios(find(aa'), :); 27 | 28 | N = 1; 29 | 30 | for i = 1:N 31 | % add robot to Model 32 | Model = addRobotToModel(Model, scenarios); 33 | name = ['random-64-64_r_' num2str(Model.robotCount) '_i_' num2str(i)]; 34 | disp(name) 35 | % save(name, 'Model') 36 | % clear Model 37 | end 38 | 39 | % % check Feasibility 40 | % isFeasible = checkFeasibility(Model); 41 | % if ~isFeasible 42 | % disp('Not Feasible!') 43 | % end 44 | 45 | % Plot 46 | plotModelMulti(Model); 47 | -------------------------------------------------------------------------------- /common/modifyPath.m: -------------------------------------------------------------------------------- 1 | function Path = modifyPath (Model, Path) 2 | 3 | pathNodeNumbers = Path.nodeNumbers; 4 | pathCoords = Path.coords; 5 | pathDirs = Path.dirs; 6 | 7 | it = 1; 8 | NumPoints = 100; 9 | 10 | while it <= size(pathCoords, 1) - 2 11 | X = linspace(pathCoords(it, 1), pathCoords(it + 2, 1), NumPoints); 12 | Y = linspace(pathCoords(it, 2), pathCoords(it + 2, 2), NumPoints); 13 | 14 | violation = zeros(1, Model.Obsts.count); 15 | 16 | for k = 1:Model.Obsts.count 17 | dd = sqrt((X - Model.Obsts.x(k)) .^ 2 + (Y - Model.Obsts.y(k)) .^ 2); 18 | v = max(1 - dd / (Model.Obsts.r), 0); 19 | violation(k) = mean(v); 20 | end 21 | 22 | Violation = any(violation); 23 | 24 | if ~Violation 25 | pathCoords(it + 1, :) = []; 26 | pathNodeNumbers(it + 1) = []; 27 | pathDirs(it + 1) = []; 28 | else 29 | it = it +1; 30 | end 31 | 32 | end 33 | 34 | Path.coords = pathCoords; 35 | Path.nodeNumbers = pathNodeNumbers; 36 | Path.dirs = pathDirs; 37 | 38 | end 39 | -------------------------------------------------------------------------------- /models/FromMapFile/addRobotToModel.m: -------------------------------------------------------------------------------- 1 | function Model = addRobotToModel(Model, scenarios) 2 | % add Robots data to Model 3 | 4 | v = randperm(size(scenarios, 1), Model.robotCount); 5 | sena = scenarios(v, :); 6 | 7 | %% robot data 8 | 9 | r.xs = 0; 10 | r.ys = 0; 11 | r.dir = 0; 12 | r.startNode = 0; 13 | r.targetNode = 0; 14 | Robots = repmat(r, Model.robotCount, 1); 15 | 16 | for iRobot = 1:Model.robotCount 17 | % start & goal - start & target coordinates 18 | Robots(iRobot).xs = sena(iRobot, 1); 19 | Robots(iRobot).ys = sena(iRobot, 2); 20 | Robots(iRobot).xt = sena(iRobot, 3); 21 | Robots(iRobot).yt = sena(iRobot, 4); 22 | 23 | Robots(iRobot).dir = deg2rad(randsample([0 90 180 270], 1)); 24 | 25 | % start & goal - node numbers 26 | Robots(iRobot).startNode = (Robots(iRobot).ys - Model.Map.yMin) * (Model.Map.nX) + Robots(iRobot).xs - Model.Map.xMin + 1; 27 | Robots(iRobot).targetNode = (Robots(iRobot).yt - Model.Map.yMin) * (Model.Map.nX) + Robots(iRobot).xt - Model.Map.xMin + 1; 28 | end 29 | 30 | %% save Model 31 | Model.Robots = Robots; 32 | 33 | end 34 | -------------------------------------------------------------------------------- /common/plotAnimation_3.m: -------------------------------------------------------------------------------- 1 | function plotAnimation_3(Sol, Model, Color) 2 | % animated points and Paths, concurrent. 3 | 4 | robotCount = Model.robotCount; 5 | 6 | h1 = cell(robotCount, 1); 7 | h2 = cell(robotCount, 1); 8 | 9 | for nr = 1:robotCount 10 | h1{nr} = animatedline('Marker', 'o', 'MarkerFaceColor', Color(nr, :), 'MarkerEdgeColor', Color(nr, :)); 11 | addpoints(h1{nr}, Sol(nr).x(1), Sol(nr).y(1)); 12 | h2{nr} = animatedline('Color', Color(nr, :), 'Color', Color(nr, :), 'LineWidth', 1); 13 | addpoints(h2{nr}, Sol(nr).x(1:2), Sol(nr).y(1:2)); 14 | drawnow 15 | end 16 | 17 | pause(1) 18 | 19 | i = 2; 20 | flag = true(robotCount, 1); 21 | 22 | while any(flag) 23 | 24 | for nr = 1:robotCount 25 | 26 | if i > numel(Sol(nr).x) 27 | flag(nr) = false; 28 | end 29 | 30 | if flag(nr) 31 | addpoints(h1{nr}, Sol(nr).x(i), Sol(nr).y(i)); 32 | addpoints(h2{nr}, Sol(nr).x(i - 1:i), Sol(nr).y(i - 1:i)); 33 | end 34 | 35 | end 36 | 37 | drawnow 38 | pause(0.4) 39 | i = i + 1; 40 | end 41 | 42 | end 43 | -------------------------------------------------------------------------------- /models/RandomModel/createSaveModelRandom.m: -------------------------------------------------------------------------------- 1 | clear 2 | clc 3 | close 4 | 5 | % add path 6 | addpath('..\..\common'); 7 | 8 | % settings 9 | Model.distType = 'manhattan'; % euclidean manhattan; 10 | Model.adjType = '4adj'; % '4adj' '8adj' 11 | Model.occLength = 1000; 12 | 13 | % createModel_rand createModel 14 | for nObst = 100 15 | 16 | for nRobot = 60 % 10:10:100 17 | disp(['nRobot ' num2str(nRobot)]) 18 | 19 | for i = 1 % 2:100 20 | Model.distType = 'manhattan'; % '4adj' '8adj' 21 | Model.adjType = '4adj'; 22 | Model = createModelRand(Model, nObst, nRobot); 23 | disp(['i' num2str(i)]) 24 | 25 | % % check Feasibility 26 | % isFeasible = checkFeasibility(Model); 27 | % if ~isFeasible 28 | % disp('Not Feasible!') 29 | % continue 30 | % end 31 | 32 | % name = ['m10x10_Obst_' num2str(nObst) '_r_' num2str(nRobot) '_i_' num2str(i)]; 33 | % save(name, 'Model'); 34 | % clear Model 35 | end 36 | 37 | end 38 | 39 | end 40 | 41 | % Plot 42 | plotModelMulti(Model); 43 | -------------------------------------------------------------------------------- /models/FromMapFile/createMapFromFile.m: -------------------------------------------------------------------------------- 1 | function [Map, map_name] = createMapFromFile(path) 2 | % read map data given in text format 3 | % Open nodes specified with '.' 4 | 5 | map_name = 'map1'; 6 | 7 | fid = fopen(path); 8 | fgetl(fid); 9 | 10 | % Height 11 | tline = fgetl(fid); 12 | H = tline; 13 | H = regexp(H, '\d*', 'Match'); 14 | H = str2num(H{1}); 15 | 16 | % Width 17 | tline = fgetl(fid); 18 | W = tline; 19 | W = regexp(W, '\d*', 'Match'); 20 | W = str2num(W{1}); 21 | 22 | % 23 | fgetl(fid); 24 | 25 | % mapCell 26 | % read each line from file and put it in mapCell 27 | iLine = 1; 28 | mapCell = cell(H, 1); 29 | tline = fgetl(fid); 30 | 31 | while ischar(tline) 32 | mapCell{iLine, 1} = tline; 33 | tline = fgetl(fid); 34 | iLine = iLine + 1; 35 | end 36 | 37 | fclose(fid); 38 | 39 | % flip mapCell 40 | mapCell = flip(mapCell); 41 | 42 | % Map Matrix 43 | % Detect Obstacles and Free Nodes (1:Free, 0:Obstacle) 44 | Map = zeros(H, W); 45 | 46 | for iLine = 1:H 47 | 48 | for j = 1:W 49 | Map(iLine, j) = strcmp(mapCell{iLine, 1}(j), '.'); 50 | end 51 | 52 | end 53 | 54 | % % save 55 | % save(name_,'Map', 'map_name'); 56 | 57 | end 58 | -------------------------------------------------------------------------------- /common/calCostLinear.m: -------------------------------------------------------------------------------- 1 | function [cost, SolChar] = calCostLinear(Model, coords) 2 | 3 | xPath = coords(:, 1); 4 | yPath = coords(:, 2); 5 | 6 | dxPath = diff(xPath); 7 | dyPath = diff(yPath); 8 | 9 | % path length 10 | L = sum(sqrt(dxPath .^ 2 + dyPath .^ 2)); 11 | 12 | % violation check, deviding path to smaller parts for violation check 13 | Temp = 100; 14 | xx = zeros(length(xPath) - 1, Temp); 15 | yy = zeros(length(xPath) - 1, Temp); 16 | 17 | for i = 1:length(xPath) - 1 18 | xx(i, :) = linspace(xPath(i), xPath(i + 1), Temp); 19 | yy(i, :) = linspace(yPath(i), yPath(i + 1), Temp); 20 | end 21 | 22 | xx = xx(:, 1:end - 1)'; 23 | xx = xx(:); xx = xx'; 24 | yy = yy(:, 1:end - 1)'; 25 | yy = yy(:); yy = yy'; 26 | 27 | violation = zeros(1, Model.Obsts.count); 28 | 29 | for i = 1:Model.Obsts.count 30 | d = sqrt((xx - Model.Obsts.x(i)) .^ 2 + (yy - Model.Obsts.y(i)) .^ 2); 31 | v = max(1 - d / (Model.Obsts.r), 0); 32 | violation(i) = mean(v); 33 | end 34 | 35 | violation = mean(violation); 36 | 37 | % solution characteristics 38 | beta = 10e10; 39 | SolChar.pathLength = L; 40 | SolChar.violation = violation; 41 | SolChar.isFeasible = (violation == 0); 42 | 43 | cost = SolChar.pathLength + beta * SolChar.violation; 44 | 45 | end 46 | -------------------------------------------------------------------------------- /MAStar/optimalPath_1.m: -------------------------------------------------------------------------------- 1 | function path = optimalPath_1(Model, Open, isPath, nr) 2 | 3 | if isPath(nr) == 1 4 | % starting from the last (target) node 5 | path_nodes(1) = Model.Robots(nr).targetNode; 6 | i = 2; 7 | 8 | % Traverse Open and determine the parent nodes 9 | parent_ind = [Open.List.nodeNumber] == path_nodes(1); 10 | parent_node = Open.List(parent_ind).pNode; 11 | time = Open.List(parent_ind).time; 12 | 13 | % going back to start node 14 | while parent_node ~= Model.Robots(nr).startNode 15 | time = time - 1; 16 | path_nodes(i) = parent_node; 17 | parent_ind = [Open.List.nodeNumber] == parent_node ... 18 | & [Open.List.time] == time; 19 | v = 1:Open.count; 20 | parent_ind = v(parent_ind); 21 | parent_ind = parent_ind(end); 22 | parent_node = Open.List(parent_ind).pNode; 23 | i = i + 1; 24 | end 25 | 26 | else 27 | path_nodes = Model.Robots(nr).startNode * [1, 1]; 28 | parent_ind = 1; 29 | end 30 | 31 | % start stall count 32 | ssc = ones(1, Open.List(parent_ind).time); 33 | 34 | if numel(ssc) > 1 35 | disp('') 36 | end 37 | 38 | path.nodeNumbers = [Model.Robots(nr).startNode * ssc, flip(path_nodes)]; 39 | path.coords = nodes2coords(path.nodeNumbers, Model); 40 | path.dirs = nodes2dirs(path.nodeNumbers, Model); 41 | 42 | end 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MRPP-MATLAB 2 | 3 | New Multi robot path planning algorithms implemented in MATLAB. 4 | Including heuristic search and incremental heuristic search methods. 5 | 6 | (Procedural programming) 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
22
15 | 16 | ## Methods 17 | 18 | - MAStar: Multi-Robot A* based path planning 19 | - ... 20 | 21 | ## Run 22 | 23 | - Go into the methods directory. 24 | - Run the **RUN_[Methods_name].m** file. 25 | - MAStar/RUN_MAStar.m 26 | 27 | 28 | ## General 29 | 30 | Apart from each path planning method's directory, there are two general directories: 31 | 32 | - **common**: common functionalities used in all planning methods 33 | - **models**: functions for creating and saving models (configurations). 34 | 35 | ## Common Settings 36 | 37 | can change this setting in the Run_[method].m file 38 | 39 | - distance type: **Model.distType** ('euclidean' or 'manhattan') 40 | - distance type: **Model.adjType** ('4adj' or '8adj') 41 | 42 | ## Configuration - Models 43 | 44 | Initial configuration includes: 45 | 46 | - Map (free nodes) 47 | - obstacles (occupied nodes) 48 | - robot's start node 49 | - robot's goal node 50 | - ... 51 | 52 | To change the configuration, you can edit the **createModel_#.m** file. 53 | 54 | ## Simulation 55 | 56 | 2 57 | -------------------------------------------------------------------------------- /common/collisionsCheck.m: -------------------------------------------------------------------------------- 1 | function collisionsCheck(Paths, robotCount) 2 | 3 | pl = zeros(1, robotCount); 4 | 5 | for j = 1:robotCount 6 | pl(j) = numel(Paths(j).nodeNumbers); 7 | end 8 | 9 | [~, ind] = sort(pl, 'descend'); 10 | 11 | % collision check 12 | for i = 1:robotCount - 1 13 | 14 | for j = i + 1:robotCount 15 | jl = pl(ind(j)); 16 | il = pl(ind(i)); 17 | 18 | for k = 1:il 19 | 20 | if k <= jl 21 | 22 | if Paths(ind(i)).nodeNumbers(k) == Paths(ind(j)).nodeNumbers(k) 23 | disp(['collision type1: robot ', num2str(ind(i)) ' and robot ' num2str(ind(j)) ', in k: ' num2str(k)]) 24 | end 25 | 26 | if k < il && k < jl && (Paths(ind(i)).nodeNumbers(k) == Paths(ind(j)).nodeNumbers(k + 1)) ... 27 | && (Paths(ind(i)).nodeNumbers(k + 1) == Paths(ind(j)).nodeNumbers(k)) 28 | disp(['collision type2: robot ', num2str(ind(i)), ' and robot ', num2str(ind(j)), ', in k: ', num2str(k)]) 29 | end 30 | 31 | end 32 | 33 | if k > jl 34 | 35 | if Paths(ind(i)).nodeNumbers(k) == Paths(ind(j)).nodeNumbers(jl) 36 | disp(['collision type3: robot ', num2str(ind(i)) ' and robot ' num2str(ind(j)) ', in k: ' num2str(k)]) 37 | end 38 | 39 | end 40 | 41 | end 42 | 43 | end 44 | 45 | end 46 | 47 | end 48 | -------------------------------------------------------------------------------- /common/plotAnimation_2.m: -------------------------------------------------------------------------------- 1 | function plotAnimation_2(Sol, Model, Color) 2 | % animated points with tale! concurrent. 3 | 4 | robotCount = Model.robotCount; 5 | 6 | h1 = zeros(robotCount, 1); 7 | h2 = zeros(robotCount, 1); 8 | 9 | for nr = 1:robotCount 10 | h1(nr) = plot(Sol(nr).x(1), Sol(nr).y(1), 'o', 'MarkerFaceColor', Color(nr, :), 'MarkerEdgeColor', Color(nr, :)); 11 | h2(nr) = plot(Sol(nr).x(1:2), Sol(nr).y(1:2), 'Color', Color(nr, :), 'LineWidth', 2); 12 | end 13 | 14 | % create gif 15 | frame = getframe(gcf); 16 | img = frame2im(frame); 17 | [img, cmap] = rgb2ind(img, 256); 18 | imwrite(img, cmap, 'animation.gif', 'gif', 'LoopCount', Inf, 'DelayTime', 1); 19 | 20 | i = 2; 21 | pause(0.2) 22 | flag = true(robotCount, 1); 23 | 24 | while any(flag) 25 | 26 | for nr = 1:robotCount 27 | 28 | if i > numel(Sol(nr).x) 29 | flag(nr) = false; 30 | end 31 | 32 | if flag(nr) 33 | 34 | set(h1(nr), 'XData', Sol(nr).x(i)) 35 | set(h1(nr), 'YData', Sol(nr).y(i)) 36 | 37 | set(h2(nr), 'XData', Sol(nr).x(i - 1:i)) 38 | set(h2(nr), 'YData', Sol(nr).y(i - 1:i)) 39 | end 40 | 41 | end 42 | 43 | % draw 44 | drawnow 45 | pause(0.2) 46 | i = i + 1; 47 | 48 | % update gif 49 | frame = getframe(gcf); 50 | img = frame2im(frame); 51 | [img, cmap] = rgb2ind(img, 256); 52 | imwrite(img, cmap, 'animation.gif', 'gif', 'WriteMode', 'append', 'DelayTime', 0.2); 53 | end 54 | 55 | end 56 | -------------------------------------------------------------------------------- /MAStar/collisionsCheck2.m: -------------------------------------------------------------------------------- 1 | function [t, robo] = collisionsCheck2(Paths, robotCount) 2 | 3 | t = 0; 4 | robo = 0; 5 | 6 | pl = zeros(1, robotCount); 7 | 8 | for j = 1:robotCount 9 | pl(j) = numel(Paths(j).nodeNumbers); 10 | end 11 | 12 | [~, ind] = sort(pl, 'descend'); 13 | 14 | % collision check 15 | for i = 1:robotCount - 1 16 | 17 | for j = i + 1:robotCount 18 | jl = pl(ind(j)); 19 | il = pl(ind(i)); 20 | 21 | for k = 1:il 22 | 23 | if k <= jl 24 | 25 | if Paths(ind(i)).nodeNumbers(k) == Paths(ind(j)).nodeNumbers(k) 26 | disp(['collision type1: robot ', num2str(ind(i)) ' and robot ' num2str(ind(j)) ', in k: ' num2str(k)]) 27 | end 28 | 29 | if k < il && k < jl && (Paths(ind(i)).nodeNumbers(k) == Paths(ind(j)).nodeNumbers(k + 1)) ... 30 | && (Paths(ind(i)).nodeNumbers(k + 1) == Paths(ind(j)).nodeNumbers(k)) 31 | disp(['collision type2: robot ', num2str(ind(i)), ' and robot ', num2str(ind(j)), ', in k: ', num2str(k)]) 32 | end 33 | 34 | end 35 | 36 | if k > jl 37 | 38 | if Paths(ind(i)).nodeNumbers(k) == Paths(ind(j)).nodeNumbers(jl) 39 | disp(['collision type3: robot ', num2str(ind(i)) ' and robot ' num2str(ind(j)) ', in k: ' num2str(k)]) 40 | robo = ind(j); 41 | t = 3; 42 | return 43 | end 44 | 45 | end 46 | 47 | end 48 | 49 | end 50 | 51 | end 52 | 53 | end 54 | -------------------------------------------------------------------------------- /MAStar/expand.m: -------------------------------------------------------------------------------- 1 | function expand = expand(topNode, Closed, Model, nr) 2 | % expand a node and find feasible successors 3 | % nodeNumber pNode gCost fCost dir 4 | 5 | robot = Model.Robots(nr); 6 | 7 | % neghbors from model 8 | nNeighbors = Model.Neighbors(topNode.nodeNumber).count; 9 | Neighbors = Model.Neighbors(topNode.nodeNumber).List; 10 | 11 | nExpand = 0; 12 | 13 | for iNeighbor = 1:nNeighbors 14 | % neighbor 15 | newX = Neighbors(iNeighbor).x; 16 | newY = Neighbors(iNeighbor).y; 17 | newDir = Neighbors(iNeighbor).dir; 18 | newCost = Neighbors(iNeighbor).cost; 19 | newNodeNumber = Neighbors(iNeighbor).nodeNumber; 20 | 21 | % add neighbor (newNode) to list if it is not in Closed list 22 | if ~any(newNodeNumber == Closed.nodeNumbers) 23 | nExpand = nExpand + 1; 24 | list(nExpand).visited = 0; 25 | list(nExpand).nodeNumber = newNodeNumber; 26 | list(nExpand).pNode = topNode.nodeNumber; 27 | list(nExpand).gCost = topNode.gCost + newCost; 28 | hCost = calDistance(robot.xt, robot.yt, newX, newY, Model.distType); 29 | list(nExpand).fCost = list(nExpand).gCost + 1 * hCost; 30 | list(nExpand).dir = newDir; 31 | list(nExpand).time = topNode.time + 1; 32 | list(nExpand).tag = 1; 33 | end 34 | 35 | end 36 | 37 | % Neighbors 38 | expand.count = nExpand; 39 | 40 | if nExpand ~= 0 41 | % dTheta = angdiff(topNode.dir*ones(1, nExpand), [list.dir]); 42 | % dTheta = abs(dTheta); 43 | % [~, sortInds] = sort(dTheta); 44 | % list = list(sortInds); 45 | expand.List = list; 46 | else 47 | expand.List = []; 48 | end 49 | 50 | end 51 | -------------------------------------------------------------------------------- /common/plotModelMulti.m: -------------------------------------------------------------------------------- 1 | function plotModelMulti(Model) 2 | 3 | xMin = Model.Map.xMin; 4 | xMax = Model.Map.xMax; 5 | yMin = Model.Map.yMin; 6 | yMax = Model.Map.yMax; 7 | obstX = Model.Obsts.x; 8 | obstY = Model.Obsts.y; 9 | Robot = Model.Robots; 10 | 11 | % figure(1) 12 | axis([xMin - 3, xMax + 3, yMin - 3, yMax + 3]) 13 | axis equal 14 | % grid minor 15 | % grid on 16 | % box on 17 | hold on 18 | 19 | g = gca; 20 | g.XTick = []; 21 | g.YTick = []; 22 | set(g, 'XColor', 'none', 'YColor', 'none') 23 | 24 | Color = hsv(Model.robotCount); 25 | 26 | % start and target nodes 27 | for nr = 1:Model.robotCount 28 | % start 29 | plot(Robot(nr).xs, Robot(nr).ys, 's', 'MarkerSize', 10, 'MarkerEdgeColor', ... 30 | Color(nr, :), 'MarkerFaceColor', Color(nr, :)); 31 | % target 32 | plot(Robot(nr).xt, Robot(nr).yt, 'diamond', 'MarkerSize', 10, 'MarkerEdgeColor', ... 33 | Color(nr, :), 'MarkerFaceColor', Color(nr, :)); 34 | % text 35 | text(Robot(nr).xs, Robot(nr).ys + 0.2, num2str(nr), 'HorizontalAlignment', 'center', ... 36 | 'FontName', 'Cambria', 'FontSize', 10) %,'FontWeight', 'bold' ys - 0.3 37 | text(Robot(nr).xt, Robot(nr).yt + 0.2, num2str(nr), 'HorizontalAlignment', 'center', ... 38 | 'FontName', 'Cambria', 'FontSize', 10) % ,'FontWeight', 'bold' yt + 0.3 39 | end 40 | 41 | % Obstacles 42 | plot(obstX, obstY, 'ko', 'MarkerSize', 5, 'MarkerFaceColor', 'k'); 43 | 44 | % theta=linspace(0,2*pi,100); 45 | % for i=1:length(xc) 46 | % fill(xc(i)+obst_r*cos(theta),yc(i)+obst_r*sin(theta),'k'); 47 | % end 48 | 49 | % walls 50 | rectangle('Position', [xMin - 2, yMin - 2, (xMax - xMin + 3), (yMax - yMin + 3)], 'LineWidth', 2) 51 | 52 | end 53 | -------------------------------------------------------------------------------- /models/checkFeasibility.m: -------------------------------------------------------------------------------- 1 | function isFeasible = checkFeasibility(Model) 2 | 3 | addpath('..\common'); 4 | addpath('..\models'); 5 | 6 | Robots = Model.Robots; 7 | isFeasible = true; 8 | 9 | % not considering other Robots 10 | for iRobot = 1:Model.robotCount 11 | Model.Robots = Robots(iRobot); 12 | 13 | try 14 | myAStar(Model); 15 | catch ME 16 | isFeasible = false; 17 | 18 | switch ME.identifier 19 | case 'Astar:noPath' 20 | disp(' No Path, case 1 !'); 21 | return 22 | otherwise 23 | rethrow(ME) 24 | disp(ME.message); 25 | end 26 | 27 | end 28 | 29 | end 30 | 31 | % not considering other Robots 32 | Model.Obsts.nodeNumber = [Model.Obsts.nodeNumber [Robots.targetNode]]; 33 | Model.Obsts.x = [Model.Obsts.x [Robots.xt]]; 34 | Model.Obsts.y = [Model.Obsts.y [Robots.yt]]; 35 | 36 | isFeasible2 = 1; 37 | 38 | for iRobot = 1:Model.robotCount 39 | Model = Model; 40 | Model.Robots = Robots(iRobot); 41 | Model.Obsts.nodeNumber(Model.Obsts.count + iRobot) = []; 42 | Model.Obsts.x(Model.Obsts.count + iRobot) = []; 43 | Model.Obsts.y(Model.Obsts.count + iRobot) = []; 44 | Model.Obsts.count = Model.Obsts.count - 1 + Model.robotCount; 45 | 46 | try 47 | myAStar(Model); 48 | catch ME 49 | isFeasible = false; 50 | 51 | switch ME.identifier 52 | case 'Astar:noPath' 53 | disp(' No Path, case 2 !'); 54 | return 55 | otherwise 56 | rethrow(ME) 57 | disp(ME.message); 58 | end 59 | 60 | end 61 | 62 | end 63 | 64 | end 65 | -------------------------------------------------------------------------------- /MAStar/neighbors8.m: -------------------------------------------------------------------------------- 1 | function neighbors = neighbors8(topNode, Closed, Model, nr) 2 | % node pNode gCost fCost dir 3 | 4 | xy = Model.Nodes.cord(:, topNode.nodeNumber); 5 | Robots = Model.Robots(nr); 6 | x = xy(1); 7 | y = xy(2); 8 | nc = 0; % neighbors.count 9 | 10 | dxdy = [1 0; 1 1; 0 1; -1 1; -1 0; -1 -1; 0 -1; 1 -1]; 11 | dirs = [0, pi / 4, pi / 2, 3 * pi / 4, pi, 5 * pi / 4, 3 * pi / 2, 7 * pi / 4]; 12 | 13 | for k = 1:8 14 | i = dxdy(k, 1); 15 | j = dxdy(k, 2); 16 | 17 | % dir 18 | nn_dir = dirs(k); 19 | 20 | % nn: new node 21 | if (i ~= j || i ~= 0) % && 22 | % The node itself is not its successor 23 | %(i==0 || j==0) % eliminate corner nodes -> 4 node 24 | nn_x = x +i; 25 | nn_y = y +j; 26 | 27 | % check if the new node is within limits 28 | if ((nn_x >= Model.xMin && nn_x <= Model.xMax) && (nn_y >= Model.yMin && nn_y <= Model.yMax)) 29 | new_node = topNode.nodeNumber + i + (j * (Model.xMax - Model.xMin + 1)); 30 | 31 | % check if it is in Closed list 32 | if ~any(new_node == Closed.nodeNumbers) 33 | nc = nc + 1; 34 | list(nc).visited = 0; 35 | list(nc).nodeNumber = new_node; 36 | list(nc).pNode = topNode.nodeNumber; 37 | list(nc).gCost = topNode.gCost + calDistance(x, y, nn_x, nn_y, Model.distType); 38 | hCost = calDistance(Robots.xt, Robots.yt, nn_x, nn_y, Model.distType) * 2; 39 | list(nc).fCost = list(nc).gCost + hCost; 40 | list(nc).dir = nn_dir; 41 | list(nc).time = topNode.time + 1; 42 | list(nc).tag = 1; 43 | end 44 | 45 | end 46 | 47 | end 48 | 49 | end 50 | 51 | neighbors.count = nc; 52 | 53 | if nc ~= 0 54 | neighbors.List = list; 55 | else 56 | neighbors.List = []; 57 | end 58 | 59 | end 60 | -------------------------------------------------------------------------------- /MAStar/initializationMh.m: -------------------------------------------------------------------------------- 1 | function [Closed, Open, Topnodes, Robots, Paths, closedInit] = initializationMh(Model) 2 | 3 | % Initialization and Parameters 4 | 5 | % nodes & obstacles 6 | obstNode = Model.obstNode; 7 | obstCount = Model.obstCount; 8 | 9 | % Robots 10 | Robots = Model.Robots; 11 | robotCount = Model.robotCount; 12 | 13 | % Closed structure 14 | cemp.count = 0; 15 | cemp.nodeNumbers = []; 16 | Closed = repmat(cemp, robotCount, 1); 17 | 18 | % Open structure 19 | oemp.count = 0; 20 | oemp.List = []; 21 | Open = repmat(oemp, robotCount, 1); 22 | 23 | % optimal path structure 24 | p.coords = []; 25 | p.nodeNumbers = []; 26 | p.dirs = []; 27 | Paths = repmat(p, robotCount, 1); 28 | 29 | %%% initialization 30 | for nr = 1:robotCount 31 | 32 | % Closed: put all obstacles on the Closed list 33 | Closed(nr).count = Closed(nr).count + obstCount; 34 | Closed(nr).nodeNumbers = [Closed(nr).nodeNumbers, obstNode]; 35 | 36 | % add target nodes to Closed lists 37 | % rv=1:robotCount; 38 | % for nnr = rv(rv~=nr) 39 | % Closed(nnr).count = Closed(nnr).count+1; 40 | % Closed(nnr).nodeNumbers(end+1) = Robots(nr).targetNode; 41 | % end 42 | 43 | % set the starting node (topNode) as the first node in Open 44 | topNode.visited = 1; 45 | topNode.nodeNumber = Robots(nr).startNode; 46 | topNode.pNode = Robots(nr).startNode; 47 | topNode.dir = Robots(nr).dir; 48 | topNode.gCost = 0; 49 | hCost = calDistance(Robots(nr).xs, Robots(nr).ys, Robots(nr).xt, Robots(nr).yt, Model.distType) * 2; 50 | topNode.fCost = topNode.gCost + hCost; 51 | topNode.time = 0; 52 | topNode.tag = 1; 53 | 54 | % insert start node in Open list 55 | Open(nr).count = 1; 56 | Open(nr).List = topNode; 57 | 58 | % add last node (hear start node) to Closed 59 | Closed(nr).count = Closed(nr).count + 1; 60 | Closed(nr).nodeNumbers(end + 1) = topNode.nodeNumber; 61 | end 62 | 63 | % Topnodes 64 | Topnodes = [Open.List]; 65 | 66 | closedInit = Closed; 67 | end 68 | -------------------------------------------------------------------------------- /MAStar/addStallNodes.m: -------------------------------------------------------------------------------- 1 | function [oTopInd, npCount, Open] = addStallNodes(npCount, Open, targetNode, dir, nr, msc) 2 | 3 | oTopInd = -1; 4 | 5 | while npCount < msc && oTopInd == -1 6 | npCount = npCount + 1; 7 | disp(['robot: ', num2str(nr), ', npCount: ', num2str(npCount)]) 8 | 9 | target_10 = Open(nr).List.nodeNumber; 10 | 11 | if any(target_10) 12 | disp('') 13 | end 14 | 15 | % delete visited nodes which were infeasible 16 | visit_ind = [Open(nr).List.visited] == 1; 17 | visit_count = sum(visit_ind); 18 | Open(nr).List = Open(nr).List(find(visit_ind)); 19 | Open(nr).count = visit_count; 20 | 21 | tag_1_ind = [Open(nr).List.tag] == 1; 22 | tag_1_count = sum(tag_1_ind); 23 | tag_1_ind = find(tag_1_ind); 24 | 25 | % sort Open list based on x 26 | [~, inds] = sort([Open(nr).List.fCost], 'ascend'); % descend ascend 27 | Open(nr).List = Open(nr).List(inds); 28 | 29 | % create stall nodes for each node in Open 30 | temp_osize = Open(nr).count; 31 | k = 1; 32 | 33 | if tag_1_count > 0 34 | 35 | for i = k:tag_1_count 36 | j = i + temp_osize; 37 | Open(nr).List(j) = Open(nr).List(tag_1_ind(i)); 38 | Open(nr).List(tag_1_ind(i)).tag = 0; 39 | Open(nr).List(j).tag = 1; 40 | Open(nr).List(tag_1_ind(i)).visited = 1; 41 | Open(nr).List(j).visited = -1; 42 | Open(nr).List(j).pNode = Open(nr).List(j).nodeNumber; 43 | Open(nr).List(j).gCost = Open(nr).List(j).gCost + 1; 44 | Open(nr).List(j).fCost = Open(nr).List(j).fCost + 1; % +i*10 45 | Open(nr).List(j).time = Open(nr).List(j).time + 1; 46 | Open(nr).count = Open(nr).count + 1; 47 | oTopInd = selectTopNode_1(Open, targetNode, dir, nr); 48 | 49 | if oTopInd ~= -1 50 | break 51 | end 52 | 53 | end 54 | 55 | % Open(nr).count = Open(nr).count+tag_1_count; 56 | % oTopInd = selectTopNode_1(Open, targetNode, dir, nr); 57 | end 58 | 59 | end 60 | 61 | end 62 | -------------------------------------------------------------------------------- /MAStar/MRPP_simple.m: -------------------------------------------------------------------------------- 1 | function Paths = MRPP_simple(Model) 2 | % MAstar, with time in Open list 3 | % with stall node 4 | 5 | % Initialization and Parameters 6 | [Closed, Open, Topnodes, robo, Paths] = initializationMh(Model); 7 | 8 | robotCount = Model.robotCount; 9 | oTopInd = zeros(robotCount, 1); % openTopInd 10 | 11 | %% Start Algorithm 12 | 13 | % defining flags 14 | isPath = ones(robotCount, 1); % was pp successful? 15 | MissionFlag = true(robotCount, 1); % is pp for robot ended? 16 | 17 | while any(MissionFlag) 18 | 19 | for nr = 1:robotCount 20 | 21 | % update mission flag 22 | MissionFlag(nr) = (Topnodes(nr).nodeNumber ~= robo(nr).targetNode && isPath(nr) == 1); 23 | 24 | if MissionFlag(nr) 25 | 26 | % finding neighbors (successors) 27 | neighbors = expand(Topnodes(nr), Closed(nr), Model, nr); 28 | 29 | % if strcmp(Model.adjType, '4adj') 30 | % neighbors = neighbors4(Topnodes(nr), Closed(nr), Model, nr); 31 | % elseif strcmp(Model.adjType, '8adj') 32 | % neighbors = neighbors8(Topnodes(nr), Closed(nr), Model, nr); 33 | % end 34 | 35 | % update or extend Open list with the successor nodes 36 | Open(nr) = updateOpen(Open(nr), neighbors); 37 | 38 | % select new Top Node 39 | oTopInd(nr) = selectTopNode_simple(Open, robo(nr).targetNode, Topnodes(nr).dir, nr); 40 | 41 | % update Open & close with new topNode 42 | if oTopInd(nr) ~= -1 43 | Open(nr).List(oTopInd(nr)).visited = 1; 44 | Topnodes(nr) = Open(nr).List(oTopInd(nr)); 45 | Closed(nr).count = Closed(nr).count + 1; 46 | Closed(nr).nodeNumbers(end + 1) = Topnodes(nr).nodeNumber; 47 | else 48 | isPath(nr) = 0; 49 | disp(['No Path for robot ' num2str(nr) '!']) 50 | end 51 | 52 | end 53 | 54 | end 55 | 56 | end 57 | 58 | %% Optimal Path 59 | for nr = 1:robotCount 60 | Paths(nr) = optimalPath_simple(Model, Open(nr), isPath, nr); 61 | end 62 | 63 | end 64 | -------------------------------------------------------------------------------- /MAStar/neighbors4.m: -------------------------------------------------------------------------------- 1 | function neighbors = neighbors4(topNode, Closed, Model, nr) 2 | % arrange neighbors based on robot direction 3 | % node pNode gCost fCost dir 4 | 5 | xy = Model.Nodes.cord(:, topNode.nodeNumber); 6 | robot = Model.Robots(nr); 7 | dir = topNode.dir; 8 | x = xy(1); 9 | y = xy(2); 10 | nc = 0; % neighbors.count 11 | 12 | % prioritize expanded node based on direction 13 | q1 = [1 0; 0 1; 0 -1; -1 0]; 14 | q2 = [-1 0; 0 1; 0 -1; 1 0]; 15 | q3 = [0 1; 1 0; -1 0; 0 -1]; 16 | q4 = [0 -1; 1 0; -1 0; 0 1]; 17 | if dir == 0 || dir == 2 * pi; qs = q1; end % 0 1 18 | if dir == pi || dir == -pi; qs = q2; end % -pi 3 19 | if dir == pi / 2; qs = q3; end % pi/2 2 20 | if dir == -pi / 2 || dir == 3 * pi / 2; qs = q4; end % -pi/2 4 21 | 22 | for k = 1:4 23 | % nn: new node 24 | i = qs(k, 1); j = qs(k, 2); 25 | 26 | % direction 27 | if all([i, j] == [1, 0]); nn_dir = 0; end 28 | if all([i, j] == [-1, 0]); nn_dir = pi; end 29 | if all([i, j] == [0, 1]); nn_dir = pi / 2; end 30 | if all([i, j] == [0, -1]); nn_dir = 3 * pi / 2; end 31 | 32 | nn_x = x + i; 33 | nn_y = y + j; 34 | 35 | % check if the new node is within limits 36 | if ((nn_x >= Model.xMin && nn_x <= Model.xMax) && (nn_y >= Model.yMin && nn_y <= Model.yMax)) 37 | new_node = topNode.nodeNumber + i + (j * (Model.xMax - Model.xMin + 1)); 38 | 39 | % check if it is in Closed list 40 | if ~any(new_node == Closed.nodeNumbers) 41 | nc = nc + 1; 42 | list(nc).visited = 0; 43 | list(nc).nodeNumber = new_node; 44 | list(nc).pNode = topNode.nodeNumber; 45 | list(nc).gCost = topNode.gCost + calDistance(x, y, nn_x, nn_y, Model.distType); 46 | hCost = calDistance(robot.xt, robot.yt, nn_x, nn_y, Model.distType); 47 | list(nc).fCost = list(nc).gCost + hCost; 48 | list(nc).dir = nn_dir; 49 | list(nc).time = topNode.time + 1; 50 | list(nc).tag = 1; 51 | end 52 | 53 | end 54 | 55 | end 56 | 57 | neighbors.count = nc; 58 | 59 | if nc ~= 0 60 | neighbors.List = list; 61 | else 62 | neighbors.List = []; 63 | end 64 | 65 | end 66 | -------------------------------------------------------------------------------- /MAStar/MRPP_1.m: -------------------------------------------------------------------------------- 1 | function Paths = MRPP_1(Model) 2 | % with stall node & time 3 | 4 | % Initialization and Parameters 5 | [Closed, Open, Topnodes, robo, Paths] = initializationMh(Model); 6 | 7 | robotCount = Model.robotCount; 8 | oTopInd = zeros(robotCount, 1); % openTopInd 9 | npCount = zeros(robotCount, 1); % no_path_count 10 | 11 | %% Start Algorithm 12 | 13 | % flags 14 | isPath = ones(robotCount, 1); % was pp successful? 15 | MissionFlag = true(robotCount, 1); % is pp for robot ended? 16 | 17 | while any(MissionFlag) 18 | 19 | for nr = 1:robotCount 20 | 21 | % update mission flag 22 | MissionFlag(nr) = (Topnodes(nr).nodeNumber ~= robo(nr).targetNode && isPath(nr) == 1); 23 | 24 | if MissionFlag(nr) 25 | 26 | % finding neighbors (successors) 27 | neighbors = expand(Topnodes(nr), Closed(nr), Model, nr); 28 | 29 | % if strcmp(Model.adjType, '4adj') 30 | % neighbors = neighbors4(Topnodes(nr), Closed(nr), Model, nr); 31 | % elseif strcmp(Model.adjType, '8adj') 32 | % neighbors = neighbors8(Topnodes(nr), Closed(nr), Model, nr); 33 | % end 34 | 35 | % update or extend Open list with the successor nodes 36 | Open(nr) = updateOpen(Open(nr), neighbors); 37 | 38 | % select new Top Node 39 | oTopInd(nr) = selectTopNode_1(Open, robo(nr).targetNode, Topnodes(nr).dir, nr); 40 | 41 | % if no path exists to the Target -> try stall nodes 42 | if oTopInd(nr) == -1 && npCount(nr) < Model.msc 43 | [oTopInd(nr), npCount(nr), Open] = addStallNodes(npCount(nr), Open ... 44 | , robo(nr).targetNode, Topnodes(nr).dir, nr, Model.msc); 45 | end 46 | 47 | % update Open & close with new topNode 48 | if oTopInd(nr) ~= -1 49 | Open(nr).List(oTopInd(nr)).visited = 1; 50 | Topnodes(nr) = Open(nr).List(oTopInd(nr)); 51 | Closed(nr).count = Closed(nr).count + 1; 52 | Closed(nr).nodeNumbers(end + 1) = Topnodes(nr).nodeNumber; 53 | else 54 | % if after trying stall nodes, no path found, robot stays at start node 55 | isPath(nr) = 0; 56 | disp(['No Path for robot ' num2str(nr) '!']) 57 | end 58 | 59 | end 60 | 61 | end 62 | 63 | end 64 | 65 | %% Optimal Path 66 | for nr = 1:robotCount 67 | Paths(nr) = optimalPath_1(Model, Open(nr), isPath, nr); 68 | end 69 | 70 | end 71 | -------------------------------------------------------------------------------- /MAStar/createModelAstar.m: -------------------------------------------------------------------------------- 1 | function Model = createModelAstar(Model) 2 | % complete base model for Astar 3 | 4 | 5 | %% neighbors 6 | 7 | Nodes = Model.Nodes; 8 | 9 | % number of neighbors 10 | switch Model.adjType 11 | case '4adj' 12 | ixy = [1 0; 0 1; 0 -1; -1 0]; 13 | nAdj = 4; 14 | case '8adj' 15 | ixy = [1 0; 0 1; 0 -1; -1 0; 1 1; -1 -1; 1 -1; -1 1]; 16 | nAdj = 8; 17 | end 18 | 19 | % distance type: euclidean manhattan 20 | switch Model.distType 21 | case 'manhattan' 22 | edgeLength = 2; 23 | case 'euclidean' 24 | edgeLength = sqrt(2); 25 | end 26 | 27 | % tempNeighbor - tempNodesNeigh 28 | tempNeighbor.nodeNumber = 0; 29 | tempNeighbor.cost = 0; 30 | tempNeighbor.dir = 0; 31 | tempNeighbor.x = 0; 32 | tempNeighbor.y = 0; 33 | tempNodesNeigh.count = 0; 34 | tempNodesNeigh.List = repmat(tempNeighbor, nAdj, 1); 35 | 36 | % Neighbors 37 | nNodes = Model.Nodes.count; 38 | Neighbors = repmat(tempNodesNeigh, nNodes, 1); 39 | 40 | for iNode = 1:nNodes 41 | Neighbors(iNode).count = 0; 42 | 43 | if ~any(iNode == Model.Obsts.nodeNumber) 44 | xNode = Nodes.cord(1, iNode); 45 | yNode = Nodes.cord(2, iNode); 46 | 47 | for iAdj = 1:nAdj 48 | ix = ixy(iAdj, 1); 49 | iy = ixy(iAdj, 2); 50 | newX = xNode + ix; 51 | newY = yNode + iy; 52 | newDir = atan2(iy, ix); 53 | 54 | % check if the Node is within array bound 55 | if (newX >= Model.Map.xMin && newX <= Model.Map.xMax) && (newY >= Model.Map.yMin && newY <= Model.Map.yMax) 56 | newNodeNumber = iNode + ix + iy * (Model.Map.nX); 57 | 58 | if ~any(newNodeNumber == Model.Obsts.nodeNumber) 59 | 60 | if ix ~= 0 && iy ~= 0 61 | cost = edgeLength; 62 | else 63 | cost = 1; 64 | end 65 | 66 | newNeighbor = tempNeighbor; 67 | newNeighbor.nodeNumber = newNodeNumber; 68 | newNeighbor.dir = newDir; 69 | newNeighbor.cost = cost; 70 | newNeighbor.x = newX; 71 | newNeighbor.y = newY; 72 | Neighbors(iNode).count = Neighbors(iNode).count + 1; 73 | Neighbors(iNode).List(Neighbors(iNode).count) = newNeighbor; 74 | end 75 | 76 | end 77 | 78 | end 79 | 80 | end 81 | 82 | end 83 | 84 | %% update model 85 | Model.Neighbors = Neighbors; 86 | 87 | %% plot model 88 | % plotModel(model); 89 | 90 | end 91 | -------------------------------------------------------------------------------- /MAStar/RUN_MAStar.m: -------------------------------------------------------------------------------- 1 | % MH Multi Robot Path Planning based on Astar - MATLAB 2 | % By Morteza Haghbeigi, m.haghbeigi@gmail.com 3 | 4 | % Initialization 5 | clc 6 | clear 7 | close 8 | 9 | % adding Paths 10 | addpath('..\common'); 11 | addpath('..\models'); 12 | 13 | %% settings 14 | Model.distType = 'manhattan'; % euclidean manhattan; 15 | Model.adjType = '4adj'; % '4adj' '8adj' 16 | 17 | %% create Model 18 | % createModel_1 createModel_2 createModel_ctest 19 | Model = createModel_1(Model); 20 | Model = createModelAstar(Model); 21 | 22 | Model.msc = 100; 23 | 24 | % % 45r_2 25 | % Model.Robots(26).targetNode = 21; 26 | % Model.Robots(26).xt = 9; 27 | % Model.Robots(26).yt = 1; 28 | 29 | robotCount = Model.robotCount; 30 | 31 | %% Preallocation 32 | % empty sol char structure 33 | % empChar.path_length = 0; 34 | % empChar.isFeasible = 0; 35 | % empChar.violation = 0; 36 | 37 | % empty sol structure 38 | % empS.solChar = empChar; 39 | empS.smoothness = 0; 40 | empS.nodeNumbers = []; 41 | empS.coords = []; 42 | empS.dirs = []; 43 | empS.cost = 0; 44 | empS.len = 0; 45 | empS.x = []; 46 | empS.y = []; 47 | empS.n = 0; 48 | 49 | % sol = repmat(empS, robotCount, 1); 50 | 51 | %% Astar MRPP 52 | % MRPP_2 MRPP_1 MRPP_simple 53 | tic 54 | Paths = MRPP_2(Model); 55 | pTime = toc; 56 | sol = Paths; 57 | 58 | for nr = 1:robotCount 59 | sol(nr).n = nr; 60 | sol(nr).len = numel(sol(nr).nodeNumbers); 61 | sol(nr).x = sol(nr).coords(:, 1); 62 | sol(nr).y = sol(nr).coords(:, 2); 63 | sol(nr).cost = calCostL(sol(nr).coords); 64 | % [sol(nr).cost, sol(nr).solChar] = calCostLinear(Model, sol(nr).coords); 65 | sol(nr).smoothness = calSmoothness(sol(nr).coords); 66 | end 67 | 68 | % sol total cost & smoothness & pTime 69 | total_pTime = toc; 70 | total_cost = sum([sol.cost]); 71 | total_smoothness = sum([sol.smoothness]); 72 | max_operation_time = max([sol.len]); 73 | tot_operation_time = sum([sol.len]); 74 | 75 | %% Paths collision check 76 | % collision check 77 | collisionsCheck(Paths, robotCount) 78 | 79 | % disp data 80 | disp(['total_cost: ' num2str(round(total_cost, 2))]) 81 | disp(['total_pTime: ' num2str(round(total_pTime, 3))]) 82 | disp(['total_smoothness: ' num2str(total_smoothness)]) 83 | disp(['max_operation_time: ' num2str(max_operation_time)]) 84 | disp(['tot_operation_time: ' num2str(tot_operation_time)]) 85 | 86 | % for i=1:robotCount 87 | % disp(sol(i)) 88 | % end 89 | 90 | % % plot solution 91 | plotModelMulti(Model) 92 | Color = hsv(robotCount); 93 | plotSolution(sol, Model, Color) % plot Paths 94 | % plotAnimation_1(sol, Model, Color) % animated points and Paths, in turn. 95 | % plotAnimation_2(sol, Model, Color) % animated points with tale! concurrent. 96 | % plotAnimation_3(sol, Model, Color) % animated points and Paths, concurrent. 97 | 98 | %% clear temporal data 99 | clear i nr Color temp_time pp_time empS empChar mod_paths distType adjType 100 | -------------------------------------------------------------------------------- /MAStar/selectTopNode_1.m: -------------------------------------------------------------------------------- 1 | function openTopInd = selectTopNode_1(Open, targetNode, dir, nr) 2 | 3 | flag = 0; 4 | flag2 = 1; 5 | robotCount = numel(Open); 6 | rv = 1:robotCount; 7 | openTopInd = -1; % 'no path!' 8 | 9 | % no_visit: not_visited_id 10 | no_visit = [Open(nr).List.visited] ~= 1; 11 | snv = sum(no_visit); 12 | 13 | if snv > 0 14 | candids = [[Open(nr).List(no_visit).fCost]; 15 | abs(angleDiff([Open(nr).List(no_visit).dir], dir)); 16 | rand(1, snv); 17 | find(no_visit)]'; 18 | 19 | [~, ind_candids] = sortrows(candids(:, 1:3)); % 1:2 20 | candids_count = numel(ind_candids); 21 | 22 | for k = 1:candids_count 23 | openTopInd = candids(ind_candids(k), end); 24 | flag = 1; 25 | 26 | for nnr = rv(rv ~= nr) 27 | % check for collision type 2 (angle_diff + pi) % (2*pi) - pi 28 | coll2 = [Open(nnr).List.visited] == 1 & [Open(nnr).List.pNode] == Open(nr).List(openTopInd).nodeNumber ... 29 | & [Open(nnr).List.nodeNumber] == Open(nr).List(openTopInd).pNode ... 30 | & [Open(nnr).List.time] == Open(nr).List(openTopInd).time; 31 | 32 | if any(coll2) 33 | flag = 0; 34 | break 35 | end 36 | 37 | % check for collision type 1 38 | coll1 = [Open(nnr).List.visited] == 1 & [Open(nnr).List.nodeNumber] == Open(nr).List(openTopInd).nodeNumber ... 39 | & [Open(nnr).List.time] == Open(nr).List(openTopInd).time; 40 | 41 | if any(coll1) 42 | flag = 0; 43 | break 44 | end 45 | 46 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 47 | % if Open(nr).List(openTopInd).nodeNumber==targetNode 48 | % tg_id=[Open(nnr).List.nodeNumber]==targetNode & [Open(nnr).List.visited]==1; 49 | % if any(tg_id) 50 | % tg_id = find(tg_id); 51 | % tg_id = tg_id(end); 52 | % dt = Open(nnr).List(tg_id).time-Open(nr).List(openTopInd).time; 53 | % if dt>0 54 | % flag=0; 55 | % % flag2=0; 56 | % break; 57 | % end 58 | % end 59 | % end 60 | 61 | end 62 | 63 | if flag2 == 0 64 | break 65 | end 66 | 67 | if flag == 1 % successful 68 | break 69 | end 70 | 71 | end 72 | 73 | end 74 | 75 | if flag == 0 % fail 76 | openTopInd = -1; 77 | end 78 | 79 | end 80 | 81 | % tg_nr_id = [Open(nr).List.nodeNumber]==targetNode; 82 | % tg_nr_id = find(tg_nr_id); 83 | % tg_nr_id = tg_nr_id(end); 84 | -------------------------------------------------------------------------------- /MAStar/createModel_ctest.m: -------------------------------------------------------------------------------- 1 | function Model = createModel_ctest(Model) 2 | 3 | %% Algorithm 4 | % max_stall_count 5 | msc = 10; 6 | 7 | %% Robots 8 | robotCount = 3; 9 | 10 | % dir: direction 11 | Robots(1).dir = -pi / 2; 12 | Robots(2).dir = -pi / 2; 13 | Robots(3).dir = -pi / 2; 14 | 15 | % start & goal 16 | Robots(1).xs = 1; Robots(1).ys = 0; 17 | Robots(1).xt = 0; Robots(1).yt = 3; 18 | 19 | Robots(2).xs = -1; Robots(2).ys = 0; 20 | Robots(2).xt = 1; Robots(2).yt = 3; 21 | 22 | Robots(3).xs = 0; Robots(3).ys = -1; 23 | Robots(3).xt = 1; Robots(3).yt = 4; 24 | 25 | %% Area 26 | limArea = 4; 27 | xMin = -1; xMax = limArea; 28 | yMin = -1; yMax = limArea; 29 | 30 | % x_node_num=xMax; 31 | % y_node_num=yMax; 32 | 33 | %%% Obstacle 34 | obst_r = 0.25; 35 | 36 | xc = [1 -1 1 2 2 2 -1]; 37 | yc = [-1 1 1 1 0 -1 -1]; 38 | 39 | %% Nodes & Adj 40 | k = 1; 41 | adj = cell(1, 1); 42 | 43 | for j = yMin:yMax 44 | 45 | for i = xMin:xMax 46 | adj{k, 1} = k; % node number 47 | adj{k, 2} = [i, j]; % node coordinates 48 | Nodes.cord(1:2, k) = [i, j]'; % node coordinates 49 | Nodes.number(1, k) = k; % node number 50 | Nodes.cost(1, k) = 0; 51 | 52 | for nr = 1:robotCount 53 | 54 | if i == Robots(nr).xs && j == Robots(nr).ys 55 | Robots(nr).startNode = k; % start node number 56 | elseif i == Robots(nr).xt && j == Robots(nr).yt 57 | Robots(nr).targetNode = k; % target (final) node number 58 | end 59 | 60 | end 61 | 62 | k = k + 1; 63 | end 64 | 65 | end 66 | 67 | Nodes.count = k - 1; 68 | 69 | % obstacle node numbers 70 | obstNode = zeros(1, length(xc)); 71 | 72 | for i = 1:length(xc) 73 | 74 | for j = 1:size(Nodes.number, 2) 75 | 76 | if xc(i) == Nodes.cord(1, j) && yc(i) == Nodes.cord(2, j) 77 | obstNode(i) = Nodes.number(j); 78 | end 79 | 80 | end 81 | 82 | end 83 | 84 | %% Map Obsts 85 | Map.lim = limArea; 86 | Map.xMin = xMin; 87 | Map.xMax = xMax; 88 | Map.yMin = yMin; 89 | Map.yMax = yMax; 90 | Map.nX = Map.xMax - Map.xMin + 1; 91 | Map.nY = Map.yMax - Map.yMin + 1; 92 | 93 | Obsts.count = numel(obstNode); 94 | Obsts.x = xc; 95 | Obsts.y = yc; 96 | Obsts.nodeNumber = obstNode; 97 | Obsts.r = obst_r; 98 | 99 | Model.robotCount = robotCount; 100 | 101 | Model.Map = Map; 102 | Model.Obsts = Obsts; 103 | 104 | %% save Model 105 | Model.robotCount = robotCount; 106 | Model.obstNode = obstNode; 107 | Model.xc = xc; Model.yc = yc; 108 | Model.obstCount = numel(xc); 109 | Model.limArea = limArea; 110 | Model.obst_r = obst_r; 111 | Model.Nodes = Nodes; 112 | Model.xMin = xMin; 113 | Model.xMax = xMax; 114 | Model.yMin = yMin; 115 | Model.yMax = yMax; 116 | Model.adj = adj; 117 | Model.Robots = Robots; 118 | Model.msc = msc; 119 | 120 | end 121 | -------------------------------------------------------------------------------- /MAStar/MRPP_2.m: -------------------------------------------------------------------------------- 1 | function Paths = MRPP_2(Model) 2 | % with stall node & time 3 | % calculate path just after each reach, with stall node * 4 | 5 | % Initialization and Parameters 6 | [Closed, Open, Topnodes, Robots, Paths, closedInit] = initializationMh(Model); 7 | robotCount = Model.robotCount; 8 | oTopInd = zeros(robotCount, 1); % openTopInd 9 | npCount = zeros(robotCount, 1); % no_path_count 10 | 11 | %% Start Algorithm 12 | 13 | % defining flags 14 | isPath = ones(robotCount, 1); % was pp successful? 15 | MissionFlag = true(robotCount, 1); % is pp for robot ended? 16 | % path_complete_flag = MissionFlag; % was optimal path calculated? 17 | 18 | robot_list = 1:robotCount; 19 | 20 | while any(MissionFlag) 21 | priority_list = priority(Robots, robot_list, Model, [Topnodes.nodeNumber]); 22 | 23 | for nr = priority_list 24 | % for nr=1:robotCount 25 | 26 | % update mission flag 27 | % MissionFlag(nr) = (Topnodes(nr).nodeNumber~=Robots(nr).targetNode && isPath(nr) == 1); 28 | if MissionFlag(nr) 29 | 30 | % finding neighbors (successors) 31 | neighbors = expand(Topnodes(nr), Closed(nr), Model, nr); 32 | 33 | % if strcmp(Model.adjType, '4adj') 34 | % neighbors = neighbors4(Topnodes(nr), Closed(nr), Model, nr); 35 | % elseif strcmp(Model.adjType, '8adj') 36 | % neighbors = neighbors8(Topnodes(nr), Closed(nr), Model, nr); 37 | % end 38 | 39 | % update or extend Open list with the successor nodes 40 | Open(nr) = updateOpen(Open(nr), neighbors); 41 | 42 | % select new Top Node 43 | oTopInd(nr) = selectTopNode_1(Open, Robots(nr).targetNode, Topnodes(nr).dir, nr); 44 | 45 | % if no path exists to the Target -> try stall nodes 46 | if oTopInd(nr) == -1 && npCount(nr) < Model.msc 47 | Closed(nr) = closedInit(nr); 48 | [oTopInd(nr), npCount(nr), Open] = addStallNodes(npCount(nr), Open ... 49 | , Robots(nr).targetNode, Topnodes(nr).dir, nr, Model.msc); 50 | end 51 | 52 | % update Open & close with new topNode 53 | if oTopInd(nr) ~= -1 54 | Open(nr).List(oTopInd(nr)).visited = 1; 55 | Topnodes(nr) = Open(nr).List(oTopInd(nr)); 56 | Closed(nr).count = Closed(nr).count + 1; 57 | Closed(nr).nodeNumbers(end + 1) = Topnodes(nr).nodeNumber; 58 | else 59 | % if after trying stall nodes, no path found, robot stays at start node 60 | isPath(nr) = 0; 61 | MissionFlag(nr) = false; 62 | disp(['No Path for robot ' num2str(nr) '!']) 63 | end 64 | 65 | if Topnodes(nr).nodeNumber == Robots(nr).targetNode 66 | MissionFlag(nr) = false; 67 | end 68 | 69 | if MissionFlag(nr) == false 70 | % Optimal Path for robot nr & update Open(nr) 71 | Paths(nr) = optimalPath_1(Model, Open(nr), isPath, nr); 72 | Open(nr) = finalOpen(Paths(nr)); 73 | end 74 | 75 | end 76 | 77 | end 78 | 79 | end 80 | 81 | end 82 | -------------------------------------------------------------------------------- /MAStar/createModel_1.m: -------------------------------------------------------------------------------- 1 | function Model = createModel_1(Model) 2 | 3 | %% Algorithm 4 | % max_stall_count 5 | msc = 10; 6 | 7 | %% Robots 8 | robotCount = 3; 9 | 10 | % dir: direction 11 | Robots(1).dir = -pi / 2; 12 | Robots(2).dir = -pi / 2; 13 | Robots(3).dir = -pi / 2; 14 | 15 | % start & goal 16 | Robots(1).xs = 1; Robots(1).ys = 4; 17 | Robots(1).xt = 21; Robots(1).yt = 14; 18 | 19 | Robots(2).xs = 25; Robots(2).ys = 4; 20 | Robots(2).xt = 4; Robots(2).yt = 14; 21 | 22 | Robots(3).xs = 5; Robots(3).ys = 7; 23 | Robots(3).xt = 1; Robots(3).yt = 12; 24 | 25 | %% Area 26 | limArea = 28; 27 | xMin = -1; xMax = limArea; 28 | yMin = -1; yMax = limArea; 29 | 30 | % x_node_num=xMax; 31 | % y_node_num=yMax; 32 | 33 | %%% Obstacle 34 | obst_r = 0.25; 35 | xc1 = [4 4 4 6 6 6 8 8 8 10 10 10 12 12 12]; 36 | yc1 = [4 5 6 4 5 6 4 5 6 4 5 6 4 5 6]; 37 | 38 | xc2 = [xc1 xc1 xc1 xc1]; 39 | yc2 = [yc1 yc1 + 6 yc1 + 12 yc1 + 18]; 40 | 41 | xc3 = xc2 + 12; 42 | yc3 = yc2; 43 | 44 | xc = [xc2 xc3]; 45 | yc = [yc2 yc3]; 46 | 47 | %% Nodes & Adj 48 | k = 1; 49 | adj = cell(1, 1); 50 | 51 | for j = yMin:yMax 52 | 53 | for i = xMin:xMax 54 | adj{k, 1} = k; % node number 55 | adj{k, 2} = [i, j]; % node coordinates 56 | Nodes.cord(1:2, k) = [i, j]'; % node coordinates 57 | Nodes.number(1, k) = k; % node number 58 | Nodes.cost(1, k) = 0; 59 | 60 | for nr = 1:robotCount 61 | 62 | if i == Robots(nr).xs && j == Robots(nr).ys 63 | Robots(nr).startNode = k; % start node number 64 | elseif i == Robots(nr).xt && j == Robots(nr).yt 65 | Robots(nr).targetNode = k; % target (final) node number 66 | end 67 | 68 | end 69 | 70 | k = k + 1; 71 | end 72 | 73 | end 74 | 75 | Nodes.count = k - 1; 76 | 77 | % obstacle node numbers 78 | obstNode = zeros(1, length(xc)); 79 | 80 | for i = 1:length(xc) 81 | 82 | for j = 1:size(Nodes.number, 2) 83 | 84 | if xc(i) == Nodes.cord(1, j) && yc(i) == Nodes.cord(2, j) 85 | obstNode(i) = Nodes.number(j); 86 | end 87 | 88 | end 89 | 90 | end 91 | 92 | %% Map Obsts 93 | Map.lim = limArea; 94 | Map.xMin = xMin; 95 | Map.xMax = xMax; 96 | Map.yMin = yMin; 97 | Map.yMax = yMax; 98 | Map.nX = Map.xMax - Map.xMin + 1; 99 | Map.nY = Map.yMax - Map.yMin + 1; 100 | 101 | Obsts.count = numel(obstNode); 102 | Obsts.x = xc; 103 | Obsts.y = yc; 104 | Obsts.nodeNumber = obstNode; 105 | Obsts.r = obst_r; 106 | 107 | Model.robotCount = robotCount; 108 | 109 | Model.Map = Map; 110 | Model.Obsts = Obsts; 111 | 112 | %% save Model 113 | Model.robotCount = robotCount; 114 | Model.obstNode = obstNode; 115 | Model.xc = xc; Model.yc = yc; 116 | Model.obstCount = numel(xc); 117 | Model.limArea = limArea; 118 | Model.obst_r = obst_r; 119 | Model.Nodes = Nodes; 120 | Model.xMin = xMin; 121 | Model.xMax = xMax; 122 | Model.yMin = yMin; 123 | Model.yMax = yMax; 124 | Model.adj = adj; 125 | Model.Robots = Robots; 126 | Model.msc = msc; 127 | 128 | end 129 | -------------------------------------------------------------------------------- /models/FromMapFile/createModelFromMap.m: -------------------------------------------------------------------------------- 1 | function Model = createModelFromMap(MapInput, Model) 2 | % Create Model from Map 3 | 4 | %% Map 5 | [H, W] = size(MapInput); 6 | Map.xMin = 0; 7 | Map.yMin = 0; 8 | Map.xMax = W - 1; 9 | Map.yMax = H - 1; 10 | Map.lim = max(W, H); 11 | Map.nX = Map.xMax - Map.xMin + 1; 12 | Map.nY = Map.yMax - Map.yMin + 1; 13 | 14 | %% Obstacles 15 | 16 | Obsts.r = 0.25; 17 | Obsts.x = []; 18 | Obsts.y = []; 19 | Obsts.nodeNumber = []; 20 | Nodes.count = H * W; 21 | Nodes.cord = zeros(2, Nodes.count); 22 | Nodes.number = zeros(1, Nodes.count); 23 | 24 | iNodeNumber = 1; 25 | 26 | for i = 1:H 27 | 28 | for j = 1:W 29 | Nodes.number(1, iNodeNumber) = iNodeNumber; 30 | Nodes.cord(:, iNodeNumber) = [j - 1, i - 1]'; 31 | 32 | if MapInput(i, j) == 0 33 | Obsts.x = [Obsts.x j - 1]; 34 | Obsts.y = [Obsts.y i - 1]; 35 | Obsts.nodeNumber = [Obsts.nodeNumber iNodeNumber]; 36 | end 37 | 38 | iNodeNumber = iNodeNumber + 1; 39 | end 40 | 41 | end 42 | 43 | Obsts.count = numel(Obsts.nodeNumber); 44 | 45 | %% edge costs, G, RHS, GV 46 | 47 | switch Model.adjType 48 | case '4adj' 49 | ixy = [1 0; 0 1; 0 -1; -1 0]; 50 | nAdj = 4; 51 | case '8adj' 52 | ixy = [1 0; 0 1; 0 -1; -1 0; 1 1; -1 -1; 1 -1; -1 1]; 53 | nAdj = 8; 54 | end 55 | 56 | % euclidean manhattan 57 | switch Model.distType 58 | case 'manhattan' 59 | edgeLength = 2; 60 | case 'euclidean' 61 | edgeLength = sqrt(2); 62 | end 63 | 64 | Successors = cell(Nodes.count, 2); 65 | Predecessors = cell(Nodes.count, 2); 66 | 67 | gv.robot = 0; 68 | GV = repmat(gv, Nodes.count, 1); 69 | 70 | for iNode = 1:Nodes.count 71 | 72 | if ~any(iNode == Obsts.nodeNumber) 73 | xNode = Nodes.cord(1, iNode); 74 | yNode = Nodes.cord(2, iNode); 75 | 76 | for iAdj = 1:nAdj 77 | ix = ixy(iAdj, 1); 78 | iy = ixy(iAdj, 2); 79 | newX = xNode + ix; 80 | newY = yNode + iy; 81 | 82 | % check if the Node is within array bound 83 | if (newX >= Map.xMin && newX <= Map.xMax) && (newY >= Map.yMin && newY <= Map.yMax) 84 | newNodeNumber = iNode + ix + iy * (Map.nX); 85 | 86 | if ~any(newNodeNumber == Obsts.nodeNumber) 87 | Successors{iNode, 1} = [Successors{iNode, 1}, newNodeNumber]; 88 | Predecessors{newNodeNumber, 1} = [Predecessors{newNodeNumber, 1}, iNode]; 89 | 90 | if ix ~= 0 && iy ~= 0 91 | cost = edgeLength; 92 | else 93 | cost = 1; 94 | end 95 | 96 | Successors{iNode, 2} = [Successors{iNode, 2}, cost]; 97 | Predecessors{newNodeNumber, 2} = [Predecessors{newNodeNumber, 1}, cost]; 98 | end 99 | 100 | end 101 | 102 | end 103 | 104 | else 105 | GV(iNode).Robots = -1; 106 | end 107 | 108 | end 109 | 110 | % G, RHS, km 111 | G = inf(Model.robotCount, Nodes.count); 112 | G = mat2cell(G, ones(1, Model.robotCount), Nodes.count); 113 | RHS = inf(Model.robotCount, Nodes.count); 114 | RHS = mat2cell(RHS, ones(1, Model.robotCount), Nodes.count); 115 | 116 | %% save Model 117 | Model.Nodes = Nodes; 118 | Model.Obsts = Obsts; 119 | Model.Map = Map; 120 | 121 | Model.Predecessors = Predecessors; 122 | Model.Successors = Successors; 123 | Model.RHS = RHS; 124 | Model.GV = GV; 125 | Model.G = G; 126 | 127 | end 128 | -------------------------------------------------------------------------------- /models/FromMapFile/random-64-64-10.map: -------------------------------------------------------------------------------- 1 | type octile 2 | height 64 3 | width 64 4 | map 5 | .@...@.@........................@...@.....@...@................. 6 | .......@.............@...@.........@.........@....@............. 7 | ......................@.........@.....................@....@.... 8 | ..@.@..@...........................@@.............@.@.....@....@ 9 | ......@..@.........@........@................................... 10 | .....@.@........@@............@...@..@......@.........@.....@... 11 | ............@........@.....@..................@...@...@@......@. 12 | ..@..........................@..........@........@.............. 13 | ......@.@..............@...........@....................@...@... 14 | @@................@....@..........................@....@.......@ 15 | .....@.................@....................@....@.......@@..... 16 | .@...........................@.............@..............@..... 17 | .@..@.....@.................@.....@@..........................@. 18 | .........@@......@.@.............@..........@................@.. 19 | ....@....@..............@..@............@..@...@..........@..... 20 | ....@............@...........@.@...@........@.....@............. 21 | ..............................................@..@.............. 22 | ..@.......@...@...............................@..........@...... 23 | ......................@.@......@.....@@.......@...@.@........... 24 | @......@..........@....@..............................@....@.... 25 | @.@..........@......@..@............@..@.......@.....@........@. 26 | ....@.....@...@..@...........@.@@@..........@@..@........@...... 27 | ...............@.....@@....................@...............@.... 28 | ..@.@..@@@.@.....@..............@...@.........@................. 29 | ..........@......@..............@........@.......@...@.......... 30 | ..................@..................................@.@.....@.. 31 | @....@...@@...@..........@....................@................. 32 | ........@.......@.@....................................@...@.@.@ 33 | @................@.........@......@..@..............@........... 34 | ....@..@..@@............@........................@.............. 35 | ..................................@..@...........@...........@.. 36 | ........@..........@.........@........@.....@..............@.@.. 37 | ................@...........@..............@........@........@.. 38 | ...@...@...........@.......@.....................@.............. 39 | .....@.............@...................@.@................@..... 40 | ...@.....@..........@@..........@..........................@.... 41 | ....@...@..............@..............@.@............@.......@.. 42 | .......@....................................@.............@..... 43 | .................@@.....@....@................@................. 44 | .....@..@..........@....@....@@.........@..@....@..@.........@.. 45 | ..@.......@.@......@..........@.@@....................@....@.... 46 | ..............@...........................@....@................ 47 | .....@...........@.............@....@........................@.. 48 | ....@......@........@........@......@..........@.....@.@........ 49 | ..@@....@..........@..@...............@.................@..@.... 50 | ..................@.........@@.....@.................@......@... 51 | ...................@.........@...@.........@........@......@.... 52 | ..@...@.....@......................................@........@... 53 | @..............@............................@.....@...@@........ 54 | ............................@............@..@......@............ 55 | .............................@.@@..........@....@......@..@..... 56 | .....@.....@................@@@.@......................@..@@.... 57 | ...@.@...@.........@............@...................@........... 58 | ....@..................@.......@@.......@..@..........@....@.@.. 59 | .....................@@...@..@...............@.......@..@......@ 60 | ...................@......@......@............@................@ 61 | .......@..@..@.@..@.@..@@..@....@@..........@................... 62 | ..................@...........................@@@...@........... 63 | ...........................@....@.........@..................... 64 | ........@..........@......@........@............................ 65 | ...............................@..................@.@........... 66 | ........................@....................@.......@........@. 67 | ..@..........................@..@...@.....@.@.........@......... 68 | @@.........@@@.............@....@..................@........@.@@ 69 | -------------------------------------------------------------------------------- /MAStar/MRPP_3.m: -------------------------------------------------------------------------------- 1 | function Paths = MRPP_3(Model) 2 | % with stall node & time 3 | % calculate path just after each reach, with stall node * 4 | 5 | % Initialization and Parameters 6 | [Closed, Open, Topnodes, Robots, Paths, closedInit] = initializationMh(Model); 7 | robotCount = Model.robotCount; 8 | oTopInd = zeros(robotCount, 1); % openTopInd 9 | npCount = zeros(robotCount, 1); % no_path_count 10 | 11 | %% Start Algorithm 12 | 13 | % defining flags 14 | isPath = ones(robotCount, 1); % was pp successful? 15 | MissionFlag = true(robotCount, 1); % is pp for robot ended? 16 | % path_complete_flag = MissionFlag; % was optimal path calculated? 17 | 18 | robot_list = 1:robotCount; 19 | success = false; 20 | ttt = 0; 21 | 22 | while ~success && ttt < 5 23 | 24 | while any(MissionFlag) 25 | priority_list = priority(Robots, robot_list, Model, [Topnodes.nodeNumber]); 26 | 27 | for nr = priority_list 28 | % for nr=1:robotCount 29 | 30 | % update mission flag 31 | % MissionFlag(nr) = (Topnodes(nr).nodeNumber~=Robots(nr).targetNode && isPath(nr) == 1); 32 | if MissionFlag(nr) 33 | 34 | % finding neighbors (successors) 35 | neighbors = expand(Topnodes(nr), Closed(nr), Model, nr); 36 | 37 | % if strcmp(Model.adjType, '4adj') 38 | % neighbors = neighbors4(Topnodes(nr), Closed(nr), Model, nr); 39 | % elseif strcmp(Model.adjType, '8adj') 40 | % neighbors = neighbors8(Topnodes(nr), Closed(nr), Model, nr); 41 | % end 42 | 43 | % update or extend Open list with the successor nodes 44 | Open(nr) = updateOpen(Open(nr), neighbors); 45 | 46 | % select new Top Node 47 | oTopInd(nr) = selectTopNode_1(Open, Robots(nr).targetNode, Topnodes(nr).dir, nr); 48 | 49 | % if no path exists to the Target -> try stall nodes 50 | if oTopInd(nr) == -1 && npCount(nr) < Model.msc 51 | Closed(nr) = closedInit(nr); 52 | [oTopInd(nr), npCount(nr), Open] = addStallNodes(npCount(nr), Open ... 53 | , Robots(nr).targetNode, Topnodes(nr).dir, nr, Model.msc); 54 | end 55 | 56 | % update Open & close with new topNode 57 | if oTopInd(nr) ~= -1 58 | Open(nr).List(oTopInd(nr)).visited = 1; 59 | Topnodes(nr) = Open(nr).List(oTopInd(nr)); 60 | Closed(nr).count = Closed(nr).count + 1; 61 | Closed(nr).nodeNumbers(end + 1) = Topnodes(nr).nodeNumber; 62 | else 63 | % if after trying stall nodes, no path found, robot stays at start node 64 | isPath(nr) = 0; 65 | MissionFlag(nr) = false; 66 | disp(['No Path for robot ' num2str(nr) '!']) 67 | end 68 | 69 | if Topnodes(nr).nodeNumber == Robots(nr).targetNode 70 | MissionFlag(nr) = false; 71 | end 72 | 73 | if MissionFlag(nr) == false 74 | % Optimal Path for robot nr & update Open(nr) 75 | Paths(nr) = optimalPath_1(Model, Open(nr), isPath, nr); 76 | Open(nr) = finalOpen(Paths(nr)); 77 | end 78 | 79 | end 80 | 81 | end 82 | 83 | end 84 | 85 | [t, robo] = collisionsCheck2(Paths, robotCount); 86 | 87 | if robo == 0 88 | success = true; 89 | else 90 | MissionFlag(robo) = true; 91 | priority_list = robo; 92 | ttt = ttt + 1; 93 | % Closed: put all obstacles on the Closed list 94 | Closed(robo).count = Model.obstCount; 95 | Closed(robo).nodeNumbers = Model.obstNode; 96 | 97 | % set the starting node (topNode) as the first node in Open 98 | topNode.visited = 1; 99 | topNode.nodeNumber = Model.Robots(robo).startNode; 100 | topNode.pNode = Model.Robots(robo).startNode; 101 | topNode.dir = Model.Robots(robo).dir; 102 | topNode.gCost = 0; 103 | hCost = calDistance(Model.Robots(robo).xs, Model.Robots(robo).ys, Model.Robots(robo).xt, Model.Robots(robo).yt, Model.distType) * 2; 104 | topNode.fCost = topNode.gCost + hCost; 105 | topNode.time = 0; 106 | topNode.tag = 1; 107 | 108 | % insert start node in Open list 109 | Open(robo).count = 1; 110 | Open(robo).List = topNode; 111 | 112 | % add last node (hear start node) to Closed 113 | Closed(robo).count = Closed(robo).count + 1; 114 | Closed(robo).nodeNumbers(end + 1) = topNode.nodeNumber; 115 | end 116 | 117 | end 118 | 119 | end 120 | -------------------------------------------------------------------------------- /models/FromExcell/createModelFromExcel.m: -------------------------------------------------------------------------------- 1 | function Model = createModelFromExcel(Model) 2 | 3 | %% read data 4 | data = xlsread('Book1.xlsx', 'Sheet6'); 5 | 6 | %% Algorithm 7 | % max_stall_count 8 | MSC = 40; 9 | 10 | %% Map 11 | Map.lim = data(1, 1); 12 | Map.xMin = 0; 13 | Map.xMax = data(1, 1); 14 | Map.yMin = 0; 15 | Map.yMax = data(2, 1); 16 | 17 | Map.nX = Map.xMax - Map.xMin + 1; 18 | Map.nY = Map.yMax - Map.yMin + 1; 19 | 20 | %% Robots data 21 | robotCount = data(1, 2); 22 | Model.robotCount = robotCount; 23 | 24 | r.dir = 0; 25 | r.xs = 0; r.ys = 0; 26 | r.xt = 0; r.yt = 0; 27 | r.targetNode = 0; 28 | r.startNode = 0; 29 | 30 | Robots = repmat(r, robotCount, 1); 31 | 32 | for iRobot = 1:robotCount 33 | j = iRobot + 6; 34 | Robots(iRobot).xs = data(1, j); 35 | Robots(iRobot).ys = data(2, j); 36 | Robots(iRobot).xt = data(3, j); 37 | Robots(iRobot).yt = data(4, j); 38 | Robots(iRobot).dir = data(5, j); 39 | end 40 | 41 | % start & goal - node numbers 42 | for iRobot = 1:robotCount 43 | Robots(iRobot).startNode = (Robots(iRobot).ys - Map.yMin) * (Map.xMax - Map.xMin + 1) + Robots(iRobot).xs - Map.xMin + 1; 44 | Robots(iRobot).targetNode = (Robots(iRobot).yt - Map.yMin) * (Map.xMax - Map.xMin + 1) + Robots(iRobot).xt - Map.xMin + 1; 45 | end 46 | 47 | %% Obstacle 48 | 49 | % radius 50 | Obsts.r = 0.25; 51 | 52 | Obsts.count = data(1, 3); 53 | Obst2.count = data(1, 4); 54 | 55 | Obsts.x = zeros(1, Obsts.count); 56 | Obsts.y = zeros(1, Obsts.count); 57 | Obsts.nodeNumber = zeros(1, Obsts.count); 58 | 59 | for iObst = 1:Obsts.count 60 | Obsts.x(iObst) = data(iObst, 4); 61 | Obsts.y(iObst) = data(iObst, 5); 62 | Obsts.nodeNumber(iObst) = (Obsts.y(iObst) - Map.yMin) * (Map.xMax - Map.xMin + 1) + Obsts.x(iObst) - Map.xMin + 1; 63 | end 64 | 65 | Obst2.x = zeros(1, Obst2.count); 66 | Obst2.y = zeros(1, Obst2.count); 67 | Obst2.nodeNumber = zeros(1, Obst2.count); 68 | 69 | for iObst = 1:Obst2.count 70 | Obst2.x(iObst) = data(iObst, 4); 71 | Obst2.y(iObst) = data(iObst, 5); 72 | Obst2.nodeNumber(iObst) = (Obst2.y(iObst) - Map.yMin) * (Map.xMax - Map.xMin + 1) + Obst2.x(iObst) - Map.xMin + 1; 73 | end 74 | 75 | %% nodes & adj data 76 | iNode = 0; 77 | 78 | for iy = Map.yMin:Map.yMax 79 | 80 | for ix = Map.xMin:Map.xMax 81 | iNode = iNode + 1; 82 | Nodes.cord(1:2, iNode) = [ix, iy]'; % node coordinates 83 | end 84 | 85 | end 86 | 87 | Nodes.count = iNode; 88 | 89 | %% edge costs, G, RHS, GV 90 | 91 | switch Model.adjType 92 | case '4adj' 93 | ixy = [1 0; 0 1; 0 -1; -1 0]; 94 | nAdj = 4; 95 | case '8adj' 96 | ixy = [1 0; 0 1; 0 -1; -1 0; 1 1; -1 -1; 1 -1; -1 1]; 97 | nAdj = 8; 98 | end 99 | 100 | % euclidean manhattan 101 | switch Model.distType 102 | case 'manhattan' 103 | edgeLength = 2; 104 | case 'euclidean' 105 | edgeLength = sqrt(2); 106 | end 107 | 108 | Successors = cell(Nodes.count, 2); 109 | Predecessors = cell(Nodes.count, 2); 110 | 111 | gv.robot = 0; 112 | GV = repmat(gv, Nodes.count, 1); 113 | 114 | for iNode = 1:Nodes.count 115 | 116 | if ~any(iNode == Obsts.nodeNumber) 117 | xNode = Nodes.cord(1, iNode); 118 | yNode = Nodes.cord(2, iNode); 119 | 120 | for iAdj = 1:nAdj 121 | ix = ixy(iAdj, 1); 122 | iy = ixy(iAdj, 2); 123 | newX = xNode + ix; 124 | newY = yNode + iy; 125 | 126 | % check if the Node is within array bound 127 | if (newX >= Map.xMin && newX <= Map.xMax) && (newY >= Map.yMin && newY <= Map.yMax) 128 | newNodeNumber = iNode + ix + iy * (Map.xMax - Map.xMin + 1); 129 | 130 | if ~any(newNodeNumber == Obsts.nodeNumber) 131 | Successors{iNode, 1} = [Successors{iNode, 1}, newNodeNumber]; 132 | Predecessors{newNodeNumber, 1} = [Predecessors{newNodeNumber, 1}, iNode]; 133 | 134 | if ix ~= 0 && iy ~= 0 135 | cost = edgeLength; 136 | else 137 | cost = 1; 138 | end 139 | 140 | Successors{iNode, 2} = [Successors{iNode, 2}, cost]; 141 | Predecessors{newNodeNumber, 2} = [Predecessors{newNodeNumber, 1}, cost]; 142 | end 143 | 144 | end 145 | 146 | end 147 | 148 | else 149 | GV(iNode).robot = -1; 150 | end 151 | 152 | end 153 | 154 | % G, RHS, km 155 | G = inf(robotCount, Nodes.count); 156 | G = mat2cell(G, ones(1, robotCount), Nodes.count); 157 | RHS = inf(robotCount, Nodes.count); 158 | RHS = mat2cell(RHS, ones(1, robotCount), Nodes.count); 159 | 160 | %% save Model 161 | Model.Nodes = Nodes; 162 | Model.Robots = Robots; 163 | Model.Obst2 = Obst2; 164 | Model.Obsts = Obsts; 165 | Model.Map = Map; 166 | 167 | Model.Predecessors = Predecessors; 168 | Model.Successors = Successors; 169 | Model.RHS = RHS; 170 | Model.GV = GV; 171 | Model.G = G; 172 | 173 | end 174 | -------------------------------------------------------------------------------- /models/RandomModel/createModelRand.m: -------------------------------------------------------------------------------- 1 | function Model = createModelRand(Model, nObst, nRobot) 2 | % Create Complete Model for MRPP - Random 3 | 4 | %% Map 5 | Map.lim = 20; 6 | Map.xMin = 1; 7 | Map.xMax = 30; 8 | Map.yMin = 1; 9 | Map.yMax = 20; 10 | 11 | Map.nX = Map.xMax - Map.xMin + 1; 12 | Map.nY = Map.yMax - Map.yMin + 1; 13 | 14 | %% Generate Random Arrangments 15 | Obsts.count = nObst; 16 | robotCount = nRobot; 17 | Model.robotCount = robotCount; 18 | 19 | nNodes = (Map.nX * Map.nY); 20 | 21 | X = zeros(Map.nX, Map.nY); 22 | Y = zeros(Map.nX, Map.nY); 23 | 24 | for iRobot = 1:Map.nX 25 | 26 | for iy = 1:Map.nY 27 | X(iRobot, iy) = Map.xMin + iRobot - 1; 28 | Y(iRobot, iy) = Map.yMin + iy - 1; 29 | end 30 | 31 | end 32 | 33 | aRand = randsample(nNodes, 2 * robotCount + Obsts.count); 34 | 35 | randStart = aRand(1:robotCount); 36 | xStart = X(randStart); 37 | yStart = Y(randStart); 38 | 39 | randTarget = aRand(robotCount + 1:2 * robotCount); 40 | xTarget = X(randTarget); 41 | yTarget = Y(randTarget); 42 | 43 | randObstacles = aRand(2 * robotCount + 1:2 * robotCount + Obsts.count); 44 | Obsts.x = X(randObstacles)'; 45 | Obsts.y = Y(randObstacles)'; 46 | 47 | % obstacle node numbers 48 | Obsts.nodeNumber = zeros(1, Obsts.count); 49 | 50 | for iObst = 1:Obsts.count 51 | Obsts.nodeNumber(iObst) = (Obsts.y(iObst) - Map.yMin) * (Map.nX) + Obsts.x(iObst) - Map.xMin + 1; 52 | end 53 | 54 | Obsts.r = 0.25; 55 | 56 | %% Robots data 57 | r.dir = 0; 58 | r.xs = 0; 59 | r.ys = 0; 60 | r.xt = 0; 61 | r.yt = 0; 62 | r.targetNode = 0; 63 | r.startNode = 0; 64 | 65 | Robot = repmat(r, robotCount, 1); 66 | 67 | for iRobot = 1:robotCount 68 | Robot(iRobot).xs = xStart(iRobot); 69 | Robot(iRobot).ys = yStart(iRobot); 70 | Robot(iRobot).xt = xTarget(iRobot); 71 | Robot(iRobot).yt = yTarget(iRobot); 72 | Robot(iRobot).dir = 0; % deg2rad(randsample([0 90 180 270], 1)); 73 | end 74 | 75 | % start & goal - node numbers 76 | for iRobot = 1:robotCount 77 | Robot(iRobot).startNode = (Robot(iRobot).ys - Map.yMin) * (Map.nX) + Robot(iRobot).xs + abs(Map.xMin - 1); 78 | Robot(iRobot).targetNode = (Robot(iRobot).yt - Map.yMin) * (Map.nX) + Robot(iRobot).xt + abs(Map.xMin - 1); 79 | end 80 | 81 | %% nodes & adj data 82 | iNode = 0; 83 | 84 | for iy = Map.yMin:Map.yMax 85 | 86 | for ix = Map.xMin:Map.xMax 87 | iNode = iNode + 1; 88 | Nodes.cord(1:2, iNode) = [ix, iy]'; % node coordinates 89 | Nodes.number(1, iNode) = iNode; % node number 90 | end 91 | 92 | end 93 | 94 | Nodes.count = iNode; 95 | 96 | %% edge costs, G, RHS, GV 97 | 98 | switch Model.adjType 99 | case '4adj' 100 | ixy = [1 0; 0 1; 0 -1; -1 0]; 101 | nAdj = 4; 102 | case '8adj' 103 | ixy = [1 0; 0 1; 0 -1; -1 0; 1 1; -1 -1; 1 -1; -1 1]; 104 | nAdj = 8; 105 | end 106 | 107 | % euclidean manhattan 108 | switch Model.distType 109 | case 'manhattan' 110 | edgeLength = 2; 111 | case 'euclidean' 112 | edgeLength = sqrt(2); 113 | end 114 | 115 | Successors = cell(Nodes.count, 2); 116 | Predecessors = cell(Nodes.count, 2); 117 | 118 | gv.robot = 0; 119 | GV = repmat(gv, Nodes.count, 1); 120 | 121 | for iNode = 1:Nodes.count 122 | 123 | if ~any(iNode == Obsts.nodeNumber) 124 | xNode = Nodes.cord(1, iNode); 125 | yNode = Nodes.cord(2, iNode); 126 | 127 | for iAdj = 1:nAdj 128 | ix = ixy(iAdj, 1); 129 | iy = ixy(iAdj, 2); 130 | newX = xNode + ix; 131 | newY = yNode + iy; 132 | 133 | % check if the Node is within array bound 134 | if (newX >= Map.xMin && newX <= Map.xMax) && (newY >= Map.yMin && newY <= Map.yMax) 135 | newNodeNumber = iNode + ix + iy * (Map.nX); 136 | 137 | if ~any(newNodeNumber == Obsts.nodeNumber) 138 | Successors{iNode, 1} = [Successors{iNode, 1}, newNodeNumber]; 139 | Predecessors{newNodeNumber, 1} = [Predecessors{newNodeNumber, 1}, iNode]; 140 | 141 | if ix ~= 0 && iy ~= 0 142 | cost = edgeLength; 143 | else 144 | cost = 1; 145 | end 146 | 147 | Successors{iNode, 2} = [Successors{iNode, 2}, cost]; 148 | Predecessors{newNodeNumber, 2} = [Predecessors{newNodeNumber, 1}, cost]; 149 | end 150 | 151 | end 152 | 153 | end 154 | 155 | else 156 | GV(iNode).robot = -1; 157 | end 158 | 159 | end 160 | 161 | % G, RHS, km 162 | G = inf(robotCount, Nodes.count); 163 | G = mat2cell(G, ones(1, robotCount), Nodes.count); 164 | RHS = inf(robotCount, Nodes.count); 165 | RHS = mat2cell(RHS, ones(1, robotCount), Nodes.count); 166 | 167 | %% save Model 168 | Model.Nodes = Nodes; 169 | Model.Robots = Robot; 170 | Model.Obsts = Obsts; 171 | Model.Map = Map; 172 | 173 | Model.Predecessors = Predecessors; 174 | Model.Successors = Successors; 175 | Model.RHS = RHS; 176 | Model.GV = GV; 177 | Model.G = G; 178 | 179 | end 180 | -------------------------------------------------------------------------------- /MAStar/createModel_2.m: -------------------------------------------------------------------------------- 1 | function Model = createModel_2(Model) 2 | 3 | %% Algorithm 4 | % max_stall_count 5 | msc = 10; 6 | 7 | %% Robots 8 | robotCount = 10; 9 | 10 | % dir: direction 11 | Robots(1).dir = 0; 12 | Robots(2).dir = -pi; 13 | Robots(3).dir = -pi; 14 | Robots(4).dir = pi / 2; 15 | Robots(5).dir = pi / 2; 16 | Robots(6).dir = pi / 2; 17 | Robots(7).dir = 0; 18 | Robots(8).dir = pi / 2; 19 | Robots(9).dir = -pi / 2; 20 | Robots(10).dir = 0; 21 | Robots(11).dir = pi / 2; 22 | Robots(12).dir = pi / 2; 23 | Robots(13).dir = pi / 2; 24 | Robots(14).dir = pi / 2; 25 | Robots(15).dir = pi / 2; 26 | Robots(16).dir = pi / 2; 27 | Robots(17).dir = pi / 2; 28 | Robots(18).dir = pi / 2; 29 | Robots(19).dir = -pi / 2; 30 | Robots(20).dir = -pi / 2; 31 | Robots(21).dir = -pi / 2; 32 | Robots(22).dir = 0; 33 | Robots(23).dir = pi / 2; 34 | Robots(24).dir = pi / 2; 35 | Robots(25).dir = pi / 2; 36 | Robots(26).dir = pi / 2; 37 | Robots(27).dir = pi / 2; 38 | Robots(28).dir = pi / 2; 39 | Robots(29).dir = pi / 2; 40 | 41 | % start & goal 42 | Robots(1).xs = 1; Robots(1).ys = 4; 43 | Robots(1).xt = 21; Robots(1).yt = 14; 44 | 45 | Robots(2).xs = 25; Robots(2).ys = 4; 46 | Robots(2).xt = 4; Robots(2).yt = 14; 47 | 48 | Robots(3).xs = 5; Robots(3).ys = 7; 49 | Robots(3).xt = 1; Robots(3).yt = 12; 50 | 51 | Robots(4).xs = 20; Robots(4).ys = 1; 52 | Robots(4).xt = 5; Robots(4).yt = 23; 53 | 54 | Robots(5).xs = 5; Robots(5).ys = 1; 55 | Robots(5).xt = 21; Robots(5).yt = 23; 56 | 57 | Robots(6).xs = 12; Robots(6).ys = 1; 58 | Robots(6).xt = 12; Robots(6).yt = 25; 59 | 60 | Robots(7).xs = 1; Robots(7).ys = 14; 61 | Robots(7).xt = 12; Robots(7).yt = 19; 62 | 63 | Robots(8).xs = 2; Robots(8).ys = 19; 64 | Robots(8).xt = 24; Robots(8).yt = 19; 65 | 66 | Robots(9).xs = 4; Robots(9).ys = 19; 67 | Robots(9).xt = 21; Robots(9).yt = 19; 68 | 69 | Robots(10).xs = 1; Robots(10).ys = 16; 70 | Robots(10).xt = 25; Robots(10).yt = 16; 71 | 72 | Robots(11).xs = 8; Robots(11).ys = 1; 73 | Robots(11).xt = 8; Robots(11).yt = 25; 74 | 75 | Robots(12).xs = 17; Robots(12).ys = 1; 76 | Robots(12).xt = 17; Robots(12).yt = 24; 77 | 78 | Robots(13).xs = 1; Robots(13).ys = 11; 79 | Robots(13).xt = 24; Robots(13).yt = 14; 80 | 81 | Robots(14).xs = 15; Robots(14).ys = 4; 82 | Robots(14).xt = 6; Robots(14).yt = 19; 83 | 84 | Robots(15).xs = 2; Robots(15).ys = 1; 85 | Robots(15).xt = 25; Robots(15).yt = 23; 86 | 87 | Robots(16).xs = 24; Robots(16).ys = 1; 88 | Robots(16).xt = 1; Robots(16).yt = 24; 89 | 90 | Robots(17).xs = 6; Robots(17).ys = 9; 91 | Robots(17).xt = 17; Robots(17).yt = 14; 92 | 93 | Robots(18).xs = 21; Robots(18).ys = 4; 94 | Robots(18).xt = 6; Robots(18).yt = 14; 95 | 96 | Robots(19).xs = 25; Robots(19).ys = 18; 97 | Robots(19).xt = 10; Robots(19).yt = 14; 98 | 99 | Robots(20).xs = 10; Robots(20).ys = 1; 100 | Robots(20).xt = 10; Robots(20).yt = 19; 101 | 102 | Robots(21).xs = 4; Robots(21).ys = 1; 103 | Robots(21).xt = 4; Robots(21).yt = 25; 104 | 105 | Robots(22).xs = 10; Robots(22).ys = 9; 106 | Robots(22).xt = 24; Robots(22).yt = 9; 107 | 108 | Robots(23).xs = 17; Robots(23).ys = 4; 109 | Robots(23).xt = 15; Robots(23).yt = 23; 110 | 111 | Robots(24).xs = 21; Robots(24).ys = 9; 112 | Robots(24).xt = 17; Robots(24).yt = 19; 113 | 114 | Robots(25).xs = 13; Robots(25).ys = 1; 115 | Robots(25).xt = 13; Robots(25).yt = 23; 116 | 117 | Robots(26).xs = 17; Robots(26).ys = 9; 118 | Robots(26).xt = 15; Robots(26).yt = 19; 119 | 120 | Robots(27).xs = 19; Robots(27).ys = 9; 121 | Robots(27).xt = 11; Robots(27).yt = 23; 122 | 123 | Robots(28).xs = 22; Robots(28).ys = 1; 124 | Robots(28).xt = 6; Robots(28).yt = 25; 125 | 126 | Robots(29).xs = 1; Robots(29).ys = 21; 127 | Robots(29).xt = 23; Robots(29).yt = 11; 128 | 129 | %% Area 130 | limArea = 28; 131 | xMin = -1; xMax = limArea; 132 | yMin = -1; yMax = limArea; 133 | 134 | % x_node_num=xMax; 135 | % y_node_num=yMax; 136 | 137 | %%% Obstacle 138 | obst_r = 0.25; 139 | xc1 = [4 4 4 6 6 6 8 8 8 10 10 10 12 12 12]; 140 | yc1 = [4 5 6 4 5 6 4 5 6 4 5 6 4 5 6]; 141 | 142 | xc2 = [xc1 xc1 xc1 xc1]; 143 | yc2 = [yc1 yc1 + 6 yc1 + 12 yc1 + 18]; 144 | 145 | xc3 = xc2 + 12; 146 | yc3 = yc2; 147 | 148 | xc = [xc2 xc3]; 149 | yc = [yc2 yc3]; 150 | 151 | %% Nodes & Adj 152 | k = 1; 153 | adj = cell(1, 1); 154 | 155 | for j = yMin:yMax 156 | 157 | for i = xMin:xMax 158 | adj{k, 1} = k; % node number 159 | adj{k, 2} = [i, j]; % node coordinates 160 | Nodes.cord(1:2, k) = [i, j]'; % node coordinates 161 | Nodes.number(1, k) = k; % node number 162 | Nodes.cost(1, k) = 0; 163 | 164 | for nr = 1:robotCount 165 | 166 | if i == Robots(nr).xs && j == Robots(nr).ys 167 | Robots(nr).startNode = k; % start node number 168 | elseif i == Robots(nr).xt && j == Robots(nr).yt 169 | Robots(nr).targetNode = k; % target (final) node number 170 | end 171 | 172 | end 173 | 174 | k = k + 1; 175 | end 176 | 177 | end 178 | 179 | Nodes.count = k - 1; 180 | 181 | % obstacle node numbers 182 | obstNode = zeros(1, length(xc)); 183 | 184 | for i = 1:length(xc) 185 | 186 | for j = 1:size(Nodes.number, 2) 187 | 188 | if xc(i) == Nodes.cord(1, j) && yc(i) == Nodes.cord(2, j) 189 | obstNode(i) = Nodes.number(j); 190 | end 191 | 192 | end 193 | 194 | end 195 | 196 | %% Map Obsts 197 | Map.lim = limArea; 198 | Map.xMin = xMin; 199 | Map.xMax = xMax; 200 | Map.yMin = yMin; 201 | Map.yMax = yMax; 202 | Map.nX = Map.xMax - Map.xMin + 1; 203 | Map.nY = Map.yMax - Map.yMin + 1; 204 | 205 | Obsts.count = numel(obstNode); 206 | Obsts.x = xc; 207 | Obsts.y = yc; 208 | Obsts.nodeNumber = obstNode; 209 | Obsts.r = obst_r; 210 | 211 | Model.robotCount = robotCount; 212 | 213 | Model.Map = Map; 214 | Model.Obsts = Obsts; 215 | 216 | %% save Model 217 | Model.robotCount = robotCount; 218 | Model.obstNode = obstNode; 219 | Model.xc = xc; Model.yc = yc; 220 | Model.obstCount = numel(xc); 221 | Model.limArea = limArea; 222 | Model.obst_r = obst_r; 223 | Model.Nodes = Nodes; 224 | Model.xMin = xMin; 225 | Model.xMax = xMax; 226 | Model.yMin = yMin; 227 | Model.yMax = yMax; 228 | Model.adj = adj; 229 | Model.Robots = Robots; 230 | Model.msc = msc; 231 | 232 | end 233 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /models/FromMapFile/random-64-64-10-random-1.scen: -------------------------------------------------------------------------------- 1 | version 1 2 | 13 random-64-64-10.map 64 64 9 30 57 16 53.79898987 3 | 6 random-64-64-10.map 64 64 42 55 21 43 25.97056274 4 | 2 random-64-64-10.map 64 64 49 13 51 5 8.82842712 5 | 11 random-64-64-10.map 64 64 60 41 43 1 47.04163055 6 | 13 random-64-64-10.map 64 64 63 46 27 13 52.01219330 7 | 8 random-64-64-10.map 64 64 62 7 33 0 32.48528137 8 | 13 random-64-64-10.map 64 64 40 1 37 53 54.07106781 9 | 7 random-64-64-10.map 64 64 30 15 54 20 28.07106781 10 | 12 random-64-64-10.map 64 64 54 25 23 60 50.18376617 11 | 10 random-64-64-10.map 64 64 32 48 51 15 41.45584412 12 | 6 random-64-64-10.map 64 64 7 53 27 40 25.97056274 13 | 7 random-64-64-10.map 64 64 41 32 17 18 30.38477631 14 | 4 random-64-64-10.map 64 64 60 1 42 3 18.82842712 15 | 10 random-64-64-10.map 64 64 24 12 4 45 41.87005768 16 | 4 random-64-64-10.map 64 64 30 60 30 46 17.07106781 17 | 6 random-64-64-10.map 64 64 24 30 7 46 25.97056274 18 | 5 random-64-64-10.map 64 64 56 63 46 46 21.14213562 19 | 9 random-64-64-10.map 64 64 23 5 9 38 38.79898987 20 | 6 random-64-64-10.map 64 64 26 17 48 4 27.97056274 21 | 10 random-64-64-10.map 64 64 42 43 11 17 42.94112549 22 | 9 random-64-64-10.map 64 64 10 18 10 53 36.65685425 23 | 7 random-64-64-10.map 64 64 35 37 8 47 31.14213562 24 | 11 random-64-64-10.map 64 64 22 24 55 47 44.28427124 25 | 3 random-64-64-10.map 64 64 26 47 13 49 13.82842712 26 | 6 random-64-64-10.map 64 64 36 32 20 16 24.38477631 27 | 4 random-64-64-10.map 64 64 13 45 22 57 16.89949493 28 | 10 random-64-64-10.map 64 64 25 42 50 13 41.69848480 29 | 11 random-64-64-10.map 64 64 9 47 50 53 44.31370850 30 | 5 random-64-64-10.map 64 64 5 63 9 43 21.65685425 31 | 6 random-64-64-10.map 64 64 34 50 59 55 27.07106781 32 | 2 random-64-64-10.map 64 64 21 28 25 37 10.65685425 33 | 4 random-64-64-10.map 64 64 37 6 43 20 16.48528137 34 | 8 random-64-64-10.map 64 64 42 10 10 2 35.31370850 35 | 9 random-64-64-10.map 64 64 17 49 50 38 38.14213562 36 | 9 random-64-64-10.map 64 64 12 14 7 50 38.07106781 37 | 7 random-64-64-10.map 64 64 32 55 58 62 30.31370850 38 | 2 random-64-64-10.map 64 64 34 26 25 21 11.07106781 39 | 11 random-64-64-10.map 64 64 53 15 48 60 47.07106781 40 | 4 random-64-64-10.map 64 64 52 27 41 18 16.48528137 41 | 14 random-64-64-10.map 64 64 60 59 6 56 56.65685425 42 | 16 random-64-64-10.map 64 64 49 11 19 63 65.59797974 43 | 11 random-64-64-10.map 64 64 3 22 41 2 46.87005768 44 | 13 random-64-64-10.map 64 64 12 35 63 37 53.48528137 45 | 9 random-64-64-10.map 64 64 26 16 60 21 36.89949493 46 | 16 random-64-64-10.map 64 64 31 61 3 7 66.76955261 47 | 5 random-64-64-10.map 64 64 21 57 4 47 22.89949493 48 | 9 random-64-64-10.map 64 64 29 44 57 25 37.04163055 49 | 17 random-64-64-10.map 64 64 60 11 0 39 71.59797974 50 | 8 random-64-64-10.map 64 64 33 24 13 50 34.87005768 51 | 5 random-64-64-10.map 64 64 62 19 43 23 20.65685425 52 | 11 random-64-64-10.map 64 64 48 3 32 44 47.62741699 53 | 7 random-64-64-10.map 64 64 42 40 15 30 31.14213562 54 | 4 random-64-64-10.map 64 64 28 5 15 17 19.14213562 55 | 10 random-64-64-10.map 64 64 59 60 24 47 40.38477631 56 | 1 random-64-64-10.map 64 64 56 31 53 28 4.24264069 57 | 4 random-64-64-10.map 64 64 3 26 20 32 19.48528137 58 | 8 random-64-64-10.map 64 64 45 44 59 14 35.79898987 59 | 8 random-64-64-10.map 64 64 29 27 62 26 33.41421356 60 | 14 random-64-64-10.map 64 64 54 41 4 26 56.79898987 61 | 9 random-64-64-10.map 64 64 52 39 45 2 39.89949493 62 | 16 random-64-64-10.map 64 64 62 51 25 4 64.08326111 63 | 11 random-64-64-10.map 64 64 5 14 6 60 47.24264069 64 | 7 random-64-64-10.map 64 64 26 34 13 8 31.97056274 65 | 2 random-64-64-10.map 64 64 16 2 26 2 10.82842712 66 | 16 random-64-64-10.map 64 64 59 16 5 48 67.84062042 67 | 11 random-64-64-10.map 64 64 34 13 30 56 46.07106781 68 | 10 random-64-64-10.map 64 64 36 40 3 62 42.69848480 69 | 6 random-64-64-10.map 64 64 33 47 58 54 27.89949493 70 | 2 random-64-64-10.map 64 64 57 19 49 19 9.41421356 71 | 18 random-64-64-10.map 64 64 60 7 10 54 73.56854248 72 | 12 random-64-64-10.map 64 64 36 60 42 14 48.48528137 73 | 4 random-64-64-10.map 64 64 6 13 18 26 18.55634918 74 | 16 random-64-64-10.map 64 64 6 28 63 50 66.11269836 75 | 9 random-64-64-10.map 64 64 18 5 39 35 39.87005768 76 | 5 random-64-64-10.map 64 64 35 31 52 25 20.07106781 77 | 9 random-64-64-10.map 64 64 25 46 59 41 36.65685425 78 | 10 random-64-64-10.map 64 64 44 32 6 35 41.48528137 79 | 9 random-64-64-10.map 64 64 24 6 12 39 37.97056274 80 | 5 random-64-64-10.map 64 64 8 17 19 32 20.14213562 81 | 7 random-64-64-10.map 64 64 39 37 20 15 31.62741699 82 | 11 random-64-64-10.map 64 64 22 17 17 61 47.48528137 83 | 4 random-64-64-10.map 64 64 56 26 55 10 16.41421356 84 | 10 random-64-64-10.map 64 64 45 53 41 11 43.65685425 85 | 2 random-64-64-10.map 64 64 47 34 41 25 11.48528137 86 | 13 random-64-64-10.map 64 64 12 45 58 23 55.11269836 87 | 10 random-64-64-10.map 64 64 27 24 61 41 41.04163055 88 | 14 random-64-64-10.map 64 64 38 19 3 59 56.84062042 89 | 9 random-64-64-10.map 64 64 48 51 14 56 38.31370850 90 | 5 random-64-64-10.map 64 64 61 16 40 20 22.65685425 91 | 12 random-64-64-10.map 64 64 57 50 21 19 51.76955261 92 | 15 random-64-64-10.map 64 64 48 61 37 3 63.38477631 93 | 11 random-64-64-10.map 64 64 10 34 47 53 44.87005768 94 | 8 random-64-64-10.map 64 64 52 12 61 44 35.72792206 95 | 10 random-64-64-10.map 64 64 62 55 41 21 42.69848480 96 | 17 random-64-64-10.map 64 64 15 6 48 62 70.25483398 97 | 5 random-64-64-10.map 64 64 35 53 16 59 21.48528137 98 | 5 random-64-64-10.map 64 64 43 45 27 54 20.55634918 99 | 1 random-64-64-10.map 64 64 28 53 21 55 7.82842712 100 | 7 random-64-64-10.map 64 64 31 14 11 32 29.21320343 101 | 2 random-64-64-10.map 64 64 54 30 60 35 8.65685425 102 | 5 random-64-64-10.map 64 64 33 23 42 5 21.72792206 103 | 14 random-64-64-10.map 64 64 53 52 9 22 57.59797974 104 | 5 random-64-64-10.map 64 64 23 3 31 22 22.89949493 105 | 7 random-64-64-10.map 64 64 24 32 50 44 30.97056274 106 | 11 random-64-64-10.map 64 64 62 5 45 42 44.62741699 107 | 9 random-64-64-10.map 64 64 39 15 53 48 39.62741699 108 | 9 random-64-64-10.map 64 64 18 28 55 30 38.65685425 109 | 8 random-64-64-10.map 64 64 35 27 9 9 34.04163055 110 | 5 random-64-64-10.map 64 64 42 34 35 52 20.89949493 111 | 11 random-64-64-10.map 64 64 54 59 9 61 46.65685425 112 | 10 random-64-64-10.map 64 64 15 37 48 18 41.45584412 113 | 7 random-64-64-10.map 64 64 42 19 63 34 28.38477631 114 | 5 random-64-64-10.map 64 64 14 20 33 27 21.89949493 115 | 5 random-64-64-10.map 64 64 23 63 36 47 22.55634918 116 | 9 random-64-64-10.map 64 64 5 45 38 53 36.31370850 117 | 5 random-64-64-10.map 64 64 54 10 32 12 23.65685425 118 | 8 random-64-64-10.map 64 64 29 61 44 35 32.79898987 119 | 13 random-64-64-10.map 64 64 18 6 31 55 55.55634918 120 | 1 random-64-64-10.map 64 64 58 25 53 23 5.82842712 121 | 5 random-64-64-10.map 64 64 18 14 8 30 21.31370850 122 | 8 random-64-64-10.map 64 64 52 40 22 52 34.97056274 123 | 15 random-64-64-10.map 64 64 57 11 22 56 61.84062042 124 | 6 random-64-64-10.map 64 64 48 12 48 38 26.82842712 125 | 9 random-64-64-10.map 64 64 11 21 20 55 37.72792206 126 | 7 random-64-64-10.map 64 64 32 10 4 17 30.89949493 127 | 6 random-64-64-10.map 64 64 25 33 4 25 24.31370850 128 | 11 random-64-64-10.map 64 64 25 60 57 29 46.59797974 129 | 9 random-64-64-10.map 64 64 40 16 57 46 37.62741699 130 | 12 random-64-64-10.map 64 64 40 28 3 55 48.76955261 131 | 2 random-64-64-10.map 64 64 55 35 48 41 10.65685425 132 | 10 random-64-64-10.map 64 64 20 34 58 29 40.07106781 133 | 15 random-64-64-10.map 64 64 61 15 5 32 63.04163055 134 | 11 random-64-64-10.map 64 64 2 60 38 37 46.11269836 135 | 12 random-64-64-10.map 64 64 24 4 59 32 48.35533905 136 | 3 random-64-64-10.map 64 64 8 28 13 17 14.24264069 137 | 7 random-64-64-10.map 64 64 23 16 50 24 31.48528137 138 | 8 random-64-64-10.map 64 64 44 0 63 24 33.04163055 139 | 5 random-64-64-10.map 64 64 4 18 25 16 21.82842712 140 | 11 random-64-64-10.map 64 64 21 7 62 13 44.89949493 141 | 11 random-64-64-10.map 64 64 40 15 22 53 46.04163055 142 | 16 random-64-64-10.map 64 64 59 59 3 36 66.11269836 143 | 4 random-64-64-10.map 64 64 15 63 4 50 18.72792206 144 | 12 random-64-64-10.map 64 64 62 3 21 24 49.69848480 145 | 3 random-64-64-10.map 64 64 31 39 43 31 15.31370850 146 | 9 random-64-64-10.map 64 64 47 26 16 37 36.14213562 147 | 6 random-64-64-10.map 64 64 45 62 58 44 25.14213562 148 | 14 random-64-64-10.map 64 64 9 20 36 63 56.52691193 149 | 1 random-64-64-10.map 64 64 20 17 20 10 7.00000000 150 | 10 random-64-64-10.map 64 64 53 7 45 45 41.31370850 151 | 9 random-64-64-10.map 64 64 57 7 42 39 38.79898987 152 | 9 random-64-64-10.map 64 64 62 42 30 27 38.79898987 153 | 1 random-64-64-10.map 64 64 23 13 18 17 6.65685425 154 | 7 random-64-64-10.map 64 64 21 8 49 4 30.24264069 155 | 3 random-64-64-10.map 64 64 10 45 1 56 15.89949493 156 | 10 random-64-64-10.map 64 64 9 58 19 19 43.14213562 157 | 4 random-64-64-10.map 64 64 20 49 7 38 18.72792206 158 | 6 random-64-64-10.map 64 64 32 14 14 32 26.62741699 159 | 13 random-64-64-10.map 64 64 45 12 18 55 54.76955261 160 | 5 random-64-64-10.map 64 64 19 24 32 9 22.14213562 161 | 3 random-64-64-10.map 64 64 45 22 38 32 13.48528137 162 | 9 random-64-64-10.map 64 64 57 1 34 27 36.69848480 163 | 10 random-64-64-10.map 64 64 37 37 4 60 43.69848480 164 | 14 random-64-64-10.map 64 64 61 55 29 10 59.42640686 165 | 6 random-64-64-10.map 64 64 53 21 44 1 24.31370850 166 | 4 random-64-64-10.map 64 64 7 55 20 63 16.89949493 167 | 13 random-64-64-10.map 64 64 27 5 7 51 54.87005768 168 | 6 random-64-64-10.map 64 64 32 4 9 7 24.82842712 169 | 2 random-64-64-10.map 64 64 0 40 5 49 11.65685425 170 | 16 random-64-64-10.map 64 64 2 33 63 28 64.48528137 171 | 4 random-64-64-10.map 64 64 15 31 15 13 18.82842712 172 | 10 random-64-64-10.map 64 64 33 19 25 57 42.14213562 173 | 14 random-64-64-10.map 64 64 37 52 20 3 56.04163055 174 | 11 random-64-64-10.map 64 64 45 25 2 32 45.89949493 175 | 15 random-64-64-10.map 64 64 52 6 13 48 60.49747467 176 | 6 random-64-64-10.map 64 64 18 35 43 37 25.82842712 177 | 6 random-64-64-10.map 64 64 28 26 17 48 26.55634918 178 | 4 random-64-64-10.map 64 64 35 42 45 56 19.89949493 179 | 3 random-64-64-10.map 64 64 37 12 45 3 12.89949493 180 | 12 random-64-64-10.map 64 64 57 6 9 3 49.24264069 181 | 14 random-64-64-10.map 64 64 60 15 11 36 57.69848480 182 | 5 random-64-64-10.map 64 64 4 13 22 23 22.72792206 183 | 6 random-64-64-10.map 64 64 27 26 22 48 24.07106781 184 | 9 random-64-64-10.map 64 64 56 24 26 43 39.87005768 185 | 12 random-64-64-10.map 64 64 25 2 1 40 49.11269836 186 | 2 random-64-64-10.map 64 64 14 51 20 45 9.65685425 187 | 10 random-64-64-10.map 64 64 54 36 14 39 42.65685425 188 | 9 random-64-64-10.map 64 64 44 29 8 34 38.07106781 189 | 13 random-64-64-10.map 64 64 10 4 37 46 54.94112549 190 | 9 random-64-64-10.map 64 64 58 53 33 30 36.87005768 191 | 2 random-64-64-10.map 64 64 36 11 34 21 10.82842712 192 | 15 random-64-64-10.map 64 64 50 2 17 50 63.42640686 193 | 7 random-64-64-10.map 64 64 7 52 33 51 30.07106781 194 | 11 random-64-64-10.map 64 64 9 50 50 58 44.89949493 195 | 4 random-64-64-10.map 64 64 12 11 26 21 19.31370850 196 | 12 random-64-64-10.map 64 64 19 25 63 8 51.62741699 197 | 3 random-64-64-10.map 64 64 14 60 21 50 13.48528137 198 | 4 random-64-64-10.map 64 64 42 23 34 9 17.31370850 199 | 3 random-64-64-10.map 64 64 39 56 28 52 13.24264069 200 | 13 random-64-64-10.map 64 64 0 45 53 50 55.07106781 201 | 4 random-64-64-10.map 64 64 16 40 33 44 18.65685425 202 | 4 random-64-64-10.map 64 64 35 17 47 3 18.97056274 203 | 3 random-64-64-10.map 64 64 62 44 52 48 13.07106781 204 | 3 random-64-64-10.map 64 64 29 41 30 28 14.24264069 205 | 4 random-64-64-10.map 64 64 52 34 57 48 16.07106781 206 | 8 random-64-64-10.map 64 64 9 57 38 49 33.14213562 207 | 5 random-64-64-10.map 64 64 14 43 17 63 21.24264069 208 | 11 random-64-64-10.map 64 64 12 27 51 16 44.14213562 209 | 1 random-64-64-10.map 64 64 29 6 36 4 7.82842712 210 | 5 random-64-64-10.map 64 64 37 49 22 33 23.38477631 211 | 5 random-64-64-10.map 64 64 10 41 20 24 21.72792206 212 | 9 random-64-64-10.map 64 64 45 5 14 16 36.14213562 213 | 8 random-64-64-10.map 64 64 57 24 26 30 34.07106781 214 | 8 random-64-64-10.map 64 64 55 29 22 32 35.07106781 215 | 8 random-64-64-10.map 64 64 12 32 42 27 32.07106781 216 | 14 random-64-64-10.map 64 64 46 54 37 0 57.72792206 217 | 11 random-64-64-10.map 64 64 62 29 18 24 46.07106781 218 | 3 random-64-64-10.map 64 64 43 4 52 14 14.31370850 219 | 3 random-64-64-10.map 64 64 1 49 15 51 14.82842712 220 | 9 random-64-64-10.map 64 64 13 44 16 8 37.24264069 221 | 5 random-64-64-10.map 64 64 15 39 18 59 21.24264069 222 | 3 random-64-64-10.map 64 64 16 60 31 62 15.82842712 223 | 7 random-64-64-10.map 64 64 4 49 11 22 31.31370850 224 | 14 random-64-64-10.map 64 64 55 63 7 40 57.52691193 225 | 7 random-64-64-10.map 64 64 42 1 59 23 30.21320343 226 | 8 random-64-64-10.map 64 64 44 18 23 42 33.28427124 227 | 6 random-64-64-10.map 64 64 0 15 5 38 25.65685425 228 | 14 random-64-64-10.map 64 64 4 51 41 13 57.42640686 229 | 7 random-64-64-10.map 64 64 32 46 57 39 29.07106781 230 | 14 random-64-64-10.map 64 64 44 60 32 8 56.97056274 231 | 12 random-64-64-10.map 64 64 33 36 4 0 51.52691193 232 | 10 random-64-64-10.map 64 64 15 18 49 3 40.21320343 233 | 18 random-64-64-10.map 64 64 2 2 49 52 74.74011536 234 | 9 random-64-64-10.map 64 64 22 63 14 30 36.89949493 235 | 8 random-64-64-10.map 64 64 54 7 60 38 33.48528137 236 | 11 random-64-64-10.map 64 64 11 26 49 14 44.14213562 237 | 16 random-64-64-10.map 64 64 6 51 50 10 64.49747467 238 | 7 random-64-64-10.map 64 64 37 47 15 62 29.97056274 239 | 10 random-64-64-10.map 64 64 47 33 7 24 43.72792206 240 | 4 random-64-64-10.map 64 64 17 37 32 34 16.24264069 241 | 13 random-64-64-10.map 64 64 58 59 37 15 52.69848480 242 | 8 random-64-64-10.map 64 64 53 58 49 26 34.48528137 243 | 15 random-64-64-10.map 64 64 38 1 9 49 60.59797974 244 | 12 random-64-64-10.map 64 64 56 51 39 7 51.04163055 245 | 3 random-64-64-10.map 64 64 61 58 47 61 15.24264069 246 | 8 random-64-64-10.map 64 64 12 57 9 27 32.07106781 247 | 1 random-64-64-10.map 64 64 29 37 30 33 4.41421356 248 | 2 random-64-64-10.map 64 64 25 58 25 47 11.00000000 249 | 4 random-64-64-10.map 64 64 61 0 63 18 18.82842712 250 | 8 random-64-64-10.map 64 64 60 34 29 24 35.14213562 251 | 14 random-64-64-10.map 64 64 51 53 35 2 58.79898987 252 | 11 random-64-64-10.map 64 64 10 38 53 31 45.89949493 253 | 5 random-64-64-10.map 64 64 36 35 18 31 20.24264069 254 | 9 random-64-64-10.map 64 64 6 5 40 4 36.65685425 255 | 3 random-64-64-10.map 64 64 38 48 49 51 12.24264069 256 | 9 random-64-64-10.map 64 64 26 8 25 44 36.41421356 257 | 8 random-64-64-10.map 64 64 25 17 23 51 35.65685425 258 | 6 random-64-64-10.map 64 64 7 10 32 16 27.48528137 259 | 9 random-64-64-10.map 64 64 49 28 15 33 36.07106781 260 | 9 random-64-64-10.map 64 64 40 56 35 19 39.07106781 261 | 8 random-64-64-10.map 64 64 35 38 9 21 34.21320343 262 | 7 random-64-64-10.map 64 64 31 37 9 18 30.45584412 263 | 5 random-64-64-10.map 64 64 44 24 44 46 22.82842712 264 | 6 random-64-64-10.map 64 64 53 8 42 29 26.14213562 265 | 12 random-64-64-10.map 64 64 15 27 49 57 49.94112549 266 | 8 random-64-64-10.map 64 64 41 3 56 32 35.21320343 267 | 16 random-64-64-10.map 64 64 57 22 3 51 66.01219330 268 | 9 random-64-64-10.map 64 64 49 8 14 18 39.14213562 269 | 14 random-64-64-10.map 64 64 59 21 7 11 56.97056274 270 | 12 random-64-64-10.map 64 64 61 46 20 30 48.79898987 271 | 17 random-64-64-10.map 64 64 13 5 50 59 69.91168823 272 | 10 random-64-64-10.map 64 64 38 27 0 35 41.89949493 273 | 7 random-64-64-10.map 64 64 13 4 40 6 28.41421356 274 | 10 random-64-64-10.map 64 64 12 61 8 22 43.48528137 275 | 9 random-64-64-10.map 64 64 43 51 17 26 39.87005768 276 | 1 random-64-64-10.map 64 64 36 50 35 55 5.41421356 277 | 6 random-64-64-10.map 64 64 19 5 3 23 25.79898987 278 | 2 random-64-64-10.map 64 64 51 26 49 18 8.82842712 279 | 14 random-64-64-10.map 64 64 6 33 53 56 57.11269836 280 | 5 random-64-64-10.map 64 64 37 25 55 19 21.07106781 281 | 3 random-64-64-10.map 64 64 13 22 0 25 14.82842712 282 | 18 random-64-64-10.map 64 64 13 51 62 2 73.98275604 283 | 1 random-64-64-10.map 64 64 24 48 21 52 5.24264069 284 | 5 random-64-64-10.map 64 64 49 1 49 21 20.82842712 285 | 13 random-64-64-10.map 64 64 56 37 5 41 53.48528137 286 | 8 random-64-64-10.map 64 64 52 7 46 39 35.07106781 287 | 11 random-64-64-10.map 64 64 6 16 34 48 45.94112549 288 | 14 random-64-64-10.map 64 64 51 29 0 16 56.38477631 289 | 8 random-64-64-10.map 64 64 47 39 20 52 32.38477631 290 | 7 random-64-64-10.map 64 64 45 0 43 26 28.24264069 291 | 11 random-64-64-10.map 64 64 31 47 13 9 46.04163055 292 | 3 random-64-64-10.map 64 64 33 16 44 14 15.00000000 293 | 8 random-64-64-10.map 64 64 56 17 29 30 32.38477631 294 | 1 random-64-64-10.map 64 64 39 53 42 54 4.00000000 295 | 11 random-64-64-10.map 64 64 62 53 20 62 46.31370850 296 | 7 random-64-64-10.map 64 64 38 50 39 22 29.24264069 297 | 8 random-64-64-10.map 64 64 31 5 53 26 33.04163055 298 | 4 random-64-64-10.map 64 64 36 45 46 59 18.72792206 299 | 14 random-64-64-10.map 64 64 56 3 3 9 56.07106781 300 | 2 random-64-64-10.map 64 64 57 60 51 55 8.07106781 301 | 4 random-64-64-10.map 64 64 2 22 7 7 17.07106781 302 | 10 random-64-64-10.map 64 64 16 49 57 52 43.07106781 303 | 16 random-64-64-10.map 64 64 52 63 40 3 64.97056274 304 | 5 random-64-64-10.map 64 64 32 27 13 27 20.41421356 305 | 11 random-64-64-10.map 64 64 51 3 27 36 44.11269836 306 | 10 random-64-64-10.map 64 64 50 12 19 37 43.11269836 307 | 7 random-64-64-10.map 64 64 57 57 60 29 29.24264069 308 | 4 random-64-64-10.map 64 64 42 24 29 17 17.07106781 309 | 9 random-64-64-10.map 64 64 51 50 17 43 37.72792206 310 | 13 random-64-64-10.map 64 64 6 41 46 10 54.01219330 311 | 12 random-64-64-10.map 64 64 48 43 63 1 48.21320343 312 | 6 random-64-64-10.map 64 64 59 1 46 20 26.14213562 313 | 18 random-64-64-10.map 64 64 25 59 60 0 75.84062042 314 | 17 random-64-64-10.map 64 64 1 36 59 62 68.76955261 315 | 6 random-64-64-10.map 64 64 57 41 34 47 25.48528137 316 | 11 random-64-64-10.map 64 64 23 54 41 17 45.62741699 317 | 9 random-64-64-10.map 64 64 16 56 27 22 38.55634918 318 | 1 random-64-64-10.map 64 64 15 2 22 4 7.82842712 319 | 17 random-64-64-10.map 64 64 6 52 62 15 71.32590179 320 | 11 random-64-64-10.map 64 64 43 63 40 17 47.82842712 321 | 13 random-64-64-10.map 64 64 41 12 42 63 53.65685425 322 | 6 random-64-64-10.map 64 64 36 36 19 18 26.21320343 323 | 9 random-64-64-10.map 64 64 3 1 38 2 36.24264069 324 | 12 random-64-64-10.map 64 64 1 46 11 1 49.14213562 325 | 8 random-64-64-10.map 64 64 46 42 41 9 35.07106781 326 | 11 random-64-64-10.map 64 64 55 12 12 17 45.07106781 327 | 11 random-64-64-10.map 64 64 12 43 55 32 47.55634918 328 | 4 random-64-64-10.map 64 64 61 22 44 23 18.24264069 329 | 7 random-64-64-10.map 64 64 30 24 33 53 30.82842712 330 | 2 random-64-64-10.map 64 64 59 39 60 48 11.41421356 331 | 5 random-64-64-10.map 64 64 53 33 39 47 20.38477631 332 | 9 random-64-64-10.map 64 64 4 32 24 58 37.21320343 333 | 6 random-64-64-10.map 64 64 25 28 43 41 24.55634918 334 | 14 random-64-64-10.map 64 64 11 19 61 3 56.62741699 335 | 12 random-64-64-10.map 64 64 34 23 7 62 50.76955261 336 | 13 random-64-64-10.map 64 64 11 62 17 12 53.07106781 337 | 13 random-64-64-10.map 64 64 1 58 46 40 52.45584412 338 | 3 random-64-64-10.map 64 64 46 48 57 47 13.65685425 339 | 11 random-64-64-10.map 64 64 50 42 8 35 46.31370850 340 | 8 random-64-64-10.map 64 64 33 32 44 3 33.55634918 341 | 6 random-64-64-10.map 64 64 42 33 17 35 27.24264069 342 | 10 random-64-64-10.map 64 64 51 18 16 35 43.21320343 343 | 9 random-64-64-10.map 64 64 15 46 49 32 39.79898987 344 | 4 random-64-64-10.map 64 64 62 8 47 17 19.31370850 345 | 12 random-64-64-10.map 64 64 49 42 22 7 49.11269836 346 | 6 random-64-64-10.map 64 64 62 35 40 29 24.48528137 347 | 11 random-64-64-10.map 64 64 17 58 62 58 45.82842712 348 | 3 random-64-64-10.map 64 64 50 39 50 51 12.82842712 349 | 16 random-64-64-10.map 64 64 16 17 56 62 64.49747467 350 | 2 random-64-64-10.map 64 64 22 26 17 17 11.65685425 351 | 4 random-64-64-10.map 64 64 27 43 35 30 16.89949493 352 | 16 random-64-64-10.map 64 64 62 11 9 39 64.59797974 353 | 3 random-64-64-10.map 64 64 31 49 28 36 14.24264069 354 | 9 random-64-64-10.map 64 64 16 30 36 1 39.04163055 355 | 3 random-64-64-10.map 64 64 39 62 51 62 12.82842712 356 | 14 random-64-64-10.map 64 64 3 19 58 22 57.89949493 357 | 3 random-64-64-10.map 64 64 35 60 37 48 13.41421356 358 | 9 random-64-64-10.map 64 64 24 50 38 20 36.38477631 359 | 1 random-64-64-10.map 64 64 36 5 41 10 7.65685425 360 | 4 random-64-64-10.map 64 64 58 18 63 2 18.65685425 361 | 7 random-64-64-10.map 64 64 0 11 16 31 28.97056274 362 | 7 random-64-64-10.map 64 64 21 32 28 60 30.89949493 363 | 17 random-64-64-10.map 64 64 20 4 60 53 68.49747467 364 | 4 random-64-64-10.map 64 64 27 38 41 45 17.48528137 365 | 4 random-64-64-10.map 64 64 29 8 13 14 18.48528137 366 | 4 random-64-64-10.map 64 64 23 39 6 34 19.07106781 367 | 6 random-64-64-10.map 64 64 42 42 18 46 27.07106781 368 | 14 random-64-64-10.map 64 64 62 33 7 31 58.07106781 369 | 13 random-64-64-10.map 64 64 33 45 2 6 54.76955261 370 | 3 random-64-64-10.map 64 64 57 59 45 50 15.72792206 371 | 11 random-64-64-10.map 64 64 12 20 51 36 46.21320343 372 | 5 random-64-64-10.map 64 64 43 18 54 3 20.14213562 373 | 7 random-64-64-10.map 64 64 29 55 28 29 28.65685425 374 | 4 random-64-64-10.map 64 64 63 51 48 56 17.65685425 375 | 15 random-64-64-10.map 64 64 12 2 20 57 61.14213562 376 | 12 random-64-64-10.map 64 64 45 37 1 52 50.79898987 377 | 10 random-64-64-10.map 64 64 38 58 63 30 40.69848480 378 | 10 random-64-64-10.map 64 64 26 18 47 52 42.69848480 379 | 11 random-64-64-10.map 64 64 3 60 40 40 45.87005768 380 | 13 random-64-64-10.map 64 64 32 11 0 51 53.84062042 381 | 8 random-64-64-10.map 64 64 39 10 18 36 35.87005768 382 | 3 random-64-64-10.map 64 64 38 6 42 18 13.65685425 383 | 12 random-64-64-10.map 64 64 61 9 14 2 49.89949493 384 | 6 random-64-64-10.map 64 64 14 33 35 18 27.79898987 385 | 13 random-64-64-10.map 64 64 13 10 61 24 53.79898987 386 | 7 random-64-64-10.map 64 64 32 59 31 30 31.65685425 387 | 3 random-64-64-10.map 64 64 31 51 19 48 14.65685425 388 | 9 random-64-64-10.map 64 64 48 25 27 52 38.04163055 389 | 5 random-64-64-10.map 64 64 5 15 24 24 23.31370850 390 | 12 random-64-64-10.map 64 64 11 8 47 35 48.94112549 391 | 10 random-64-64-10.map 64 64 41 6 3 18 42.97056274 392 | 6 random-64-64-10.map 64 64 37 21 60 24 25.07106781 393 | 3 random-64-64-10.map 64 64 57 49 44 51 13.82842712 394 | 10 random-64-64-10.map 64 64 39 27 21 60 42.21320343 395 | 6 random-64-64-10.map 64 64 24 10 5 23 24.97056274 396 | 7 random-64-64-10.map 64 64 27 60 41 38 28.38477631 397 | 8 random-64-64-10.map 64 64 25 9 59 13 35.65685425 398 | 9 random-64-64-10.map 64 64 2 51 23 21 39.28427124 399 | 12 random-64-64-10.map 64 64 0 1 44 19 51.45584412 400 | 5 random-64-64-10.map 64 64 29 56 51 58 22.82842712 401 | 7 random-64-64-10.map 64 64 26 12 34 37 28.31370850 402 | 5 random-64-64-10.map 64 64 5 12 13 30 21.31370850 403 | 15 random-64-64-10.map 64 64 12 22 62 0 60.52691193 404 | 4 random-64-64-10.map 64 64 23 40 18 23 19.07106781 405 | 18 random-64-64-10.map 64 64 63 32 5 3 72.25483398 406 | 6 random-64-64-10.map 64 64 56 15 34 2 27.38477631 407 | 11 random-64-64-10.map 64 64 62 25 26 44 44.45584412 408 | 3 random-64-64-10.map 64 64 40 48 51 42 13.48528137 409 | 2 random-64-64-10.map 64 64 42 37 44 27 10.82842712 410 | 5 random-64-64-10.map 64 64 9 32 6 12 21.82842712 411 | 11 random-64-64-10.map 64 64 33 54 0 31 45.45584412 412 | 5 random-64-64-10.map 64 64 33 14 50 7 20.48528137 413 | 1 random-64-64-10.map 64 64 37 43 43 43 6.00000000 414 | 14 random-64-64-10.map 64 64 1 31 57 32 58.07106781 415 | 5 random-64-64-10.map 64 64 27 46 41 35 20.89949493 416 | 14 random-64-64-10.map 64 64 16 63 23 6 59.89949493 417 | 10 random-64-64-10.map 64 64 23 37 9 2 41.97056274 418 | 6 random-64-64-10.map 64 64 53 55 58 30 27.65685425 419 | 15 random-64-64-10.map 64 64 63 42 25 0 61.25483398 420 | 14 random-64-64-10.map 64 64 54 0 56 55 58.07106781 421 | 3 random-64-64-10.map 64 64 5 36 16 45 15.89949493 422 | 10 random-64-64-10.map 64 64 1 6 9 46 43.89949493 423 | 7 random-64-64-10.map 64 64 53 47 41 23 30.38477631 424 | 18 random-64-64-10.map 64 64 12 58 57 8 72.74011536 425 | 8 random-64-64-10.map 64 64 39 45 6 46 34.24264069 426 | 7 random-64-64-10.map 64 64 40 55 18 39 29.79898987 427 | 12 random-64-64-10.map 64 64 58 27 22 55 49.94112549 428 | 11 random-64-64-10.map 64 64 6 53 49 44 46.72792206 429 | 7 random-64-64-10.map 64 64 24 9 52 15 30.48528137 430 | 6 random-64-64-10.map 64 64 22 29 2 12 27.62741699 431 | 2 random-64-64-10.map 64 64 41 60 46 52 10.65685425 432 | 4 random-64-64-10.map 64 64 11 40 3 27 17.48528137 433 | 10 random-64-64-10.map 64 64 57 26 43 61 40.79898987 434 | 2 random-64-64-10.map 64 64 27 57 20 60 8.24264069 435 | 4 random-64-64-10.map 64 64 34 63 30 45 19.65685425 436 | 4 random-64-64-10.map 64 64 46 53 35 41 18.89949493 437 | 6 random-64-64-10.map 64 64 27 59 36 37 26.89949493 438 | 14 random-64-64-10.map 64 64 54 61 15 24 58.42640686 439 | 9 random-64-64-10.map 64 64 35 44 3 54 36.14213562 440 | 2 random-64-64-10.map 64 64 14 9 14 0 9.00000000 441 | 4 random-64-64-10.map 64 64 49 53 53 38 16.65685425 442 | 2 random-64-64-10.map 64 64 58 57 53 53 9.82842712 443 | 1 random-64-64-10.map 64 64 4 38 11 37 7.41421356 444 | 13 random-64-64-10.map 64 64 54 8 18 40 53.59797974 445 | 6 random-64-64-10.map 64 64 37 42 57 27 27.38477631 446 | 3 random-64-64-10.map 64 64 61 50 58 38 13.24264069 447 | 2 random-64-64-10.map 64 64 43 12 36 17 9.65685425 448 | 2 random-64-64-10.map 64 64 18 60 20 51 11.24264069 449 | 10 random-64-64-10.map 64 64 48 2 9 6 40.65685425 450 | 1 random-64-64-10.map 64 64 3 15 6 20 6.24264069 451 | 11 random-64-64-10.map 64 64 63 49 24 62 44.38477631 452 | 8 random-64-64-10.map 64 64 26 56 27 23 34.82842712 453 | 8 random-64-64-10.map 64 64 30 57 21 25 35.72792206 454 | 1 random-64-64-10.map 64 64 30 17 26 14 5.82842712 455 | 5 random-64-64-10.map 64 64 36 41 24 22 23.97056274 456 | 4 random-64-64-10.map 64 64 62 31 48 32 16.41421356 457 | 9 random-64-64-10.map 64 64 41 1 39 39 39.41421356 458 | 9 random-64-64-10.map 64 64 25 32 58 39 36.48528137 459 | 7 random-64-64-10.map 64 64 38 29 58 12 28.21320343 460 | 18 random-64-64-10.map 64 64 63 62 4 34 72.01219330 461 | 12 random-64-64-10.map 64 64 55 14 53 60 48.48528137 462 | 19 random-64-64-10.map 64 64 58 9 7 63 79.81118317 463 | 6 random-64-64-10.map 64 64 15 9 10 31 24.65685425 464 | 6 random-64-64-10.map 64 64 39 30 52 9 27.55634918 465 | 4 random-64-64-10.map 64 64 4 55 16 43 18.14213562 466 | 12 random-64-64-10.map 64 64 56 43 7 42 50.82842712 467 | 11 random-64-64-10.map 64 64 35 26 59 58 44.87005768 468 | 12 random-64-64-10.map 64 64 10 35 55 45 49.14213562 469 | 11 random-64-64-10.map 64 64 39 18 42 61 45.65685425 470 | 7 random-64-64-10.map 64 64 5 53 6 24 30.82842712 471 | 7 random-64-64-10.map 64 64 27 47 2 35 30.55634918 472 | 15 random-64-64-10.map 64 64 60 57 3 47 61.97056274 473 | 1 random-64-64-10.map 64 64 49 58 56 59 7.41421356 474 | 8 random-64-64-10.map 64 64 9 10 30 34 35.04163055 475 | 6 random-64-64-10.map 64 64 46 32 37 54 25.72792206 476 | 9 random-64-64-10.map 64 64 52 47 46 13 39.31370850 477 | 11 random-64-64-10.map 64 64 3 29 42 48 47.45584412 478 | 8 random-64-64-10.map 64 64 54 17 24 26 34.31370850 479 | 12 random-64-64-10.map 64 64 3 13 48 0 50.38477631 480 | 9 random-64-64-10.map 64 64 23 29 55 41 37.55634918 481 | 6 random-64-64-10.map 64 64 14 53 20 33 24.72792206 482 | 4 random-64-64-10.map 64 64 35 9 20 14 17.07106781 483 | 4 random-64-64-10.map 64 64 48 27 33 38 19.55634918 484 | 18 random-64-64-10.map 64 64 1 7 47 58 74.74011536 485 | 14 random-64-64-10.map 64 64 9 0 2 57 59.89949493 486 | 4 random-64-64-10.map 64 64 46 56 60 49 17.48528137 487 | 9 random-64-64-10.map 64 64 63 60 36 39 36.28427124 488 | 7 random-64-64-10.map 64 64 51 27 27 17 28.14213562 489 | 9 random-64-64-10.map 64 64 43 36 8 46 39.14213562 490 | 5 random-64-64-10.map 64 64 41 46 20 42 22.65685425 491 | 11 random-64-64-10.map 64 64 59 42 15 36 46.48528137 492 | 3 random-64-64-10.map 64 64 38 35 51 31 14.65685425 493 | 1 random-64-64-10.map 64 64 58 28 51 30 7.82842712 494 | 15 random-64-64-10.map 64 64 36 53 16 0 61.28427124 495 | 8 random-64-64-10.map 64 64 42 44 54 18 32.14213562 496 | 19 random-64-64-10.map 64 64 62 23 3 63 76.74011536 497 | 11 random-64-64-10.map 64 64 15 42 58 41 44.24264069 498 | 9 random-64-64-10.map 64 64 58 32 23 24 38.31370850 499 | 2 random-64-64-10.map 64 64 20 13 28 15 8.82842712 500 | 8 random-64-64-10.map 64 64 56 9 52 43 35.65685425 501 | 2 random-64-64-10.map 64 64 53 6 46 3 8.24264069 502 | 7 random-64-64-10.map 64 64 30 30 0 32 30.82842712 503 | 17 random-64-64-10.map 64 64 55 54 1 16 71.49747467 504 | 17 random-64-64-10.map 64 64 25 52 63 0 70.08326111 505 | 8 random-64-64-10.map 64 64 30 49 57 31 35.04163055 506 | 5 random-64-64-10.map 64 64 55 31 62 52 23.89949493 507 | 13 random-64-64-10.map 64 64 41 53 6 21 52.35533905 508 | 2 random-64-64-10.map 64 64 19 8 28 10 10.65685425 509 | 5 random-64-64-10.map 64 64 61 26 50 41 20.72792206 510 | 16 random-64-64-10.map 64 64 28 59 4 4 65.52691193 511 | 4 random-64-64-10.map 64 64 31 25 16 24 16.82842712 512 | 11 random-64-64-10.map 64 64 12 26 49 50 47.52691193 513 | 9 random-64-64-10.map 64 64 11 42 2 8 38.31370850 514 | 6 random-64-64-10.map 64 64 55 22 34 35 26.38477631 515 | 7 random-64-64-10.map 64 64 28 9 56 2 30.89949493 516 | 14 random-64-64-10.map 64 64 14 52 29 1 57.21320343 517 | 12 random-64-64-10.map 64 64 59 48 55 2 49.07106781 518 | 2 random-64-64-10.map 64 64 31 59 39 57 8.82842712 519 | 13 random-64-64-10.map 64 64 0 22 51 28 53.48528137 520 | 8 random-64-64-10.map 64 64 41 36 60 62 35.04163055 521 | 8 random-64-64-10.map 64 64 10 20 42 22 33.65685425 522 | 10 random-64-64-10.map 64 64 49 45 35 10 40.79898987 523 | 13 random-64-64-10.map 64 64 55 62 51 9 55.48528137 524 | 7 random-64-64-10.map 64 64 37 4 53 27 31.38477631 525 | 9 random-64-64-10.map 64 64 56 47 27 31 37.04163055 526 | 8 random-64-64-10.map 64 64 28 11 6 31 33.21320343 527 | 12 random-64-64-10.map 64 64 14 28 47 59 48.18376617 528 | 5 random-64-64-10.map 64 64 41 31 37 51 22.24264069 529 | 6 random-64-64-10.map 64 64 42 4 26 22 25.79898987 530 | 8 random-64-64-10.map 64 64 28 35 5 11 35.28427124 531 | 5 random-64-64-10.map 64 64 32 61 30 43 20.48528137 532 | 10 random-64-64-10.map 64 64 51 38 15 21 43.62741699 533 | 6 random-64-64-10.map 64 64 56 48 51 23 27.07106781 534 | 9 random-64-64-10.map 64 64 30 9 11 41 39.87005768 535 | 7 random-64-64-10.map 64 64 10 3 26 27 31.79898987 536 | 12 random-64-64-10.map 64 64 43 0 9 28 48.52691193 537 | 9 random-64-64-10.map 64 64 49 27 37 62 39.97056274 538 | 9 random-64-64-10.map 64 64 54 43 19 50 38.48528137 539 | 8 random-64-64-10.map 64 64 30 19 47 47 35.62741699 540 | 6 random-64-64-10.map 64 64 28 30 7 15 27.79898987 541 | 4 random-64-64-10.map 64 64 14 27 11 44 18.82842712 542 | 8 random-64-64-10.map 64 64 15 47 37 23 34.87005768 543 | 10 random-64-64-10.map 64 64 14 11 9 51 42.07106781 544 | 2 random-64-64-10.map 64 64 56 61 60 51 11.65685425 545 | 15 random-64-64-10.map 64 64 5 16 53 46 63.59797974 546 | 5 random-64-64-10.map 64 64 46 14 32 28 20.38477631 547 | 5 random-64-64-10.map 64 64 51 24 44 44 22.89949493 548 | 12 random-64-64-10.map 64 64 35 6 17 47 48.45584412 549 | 20 random-64-64-10.map 64 64 1 1 59 47 80.56854248 550 | 4 random-64-64-10.map 64 64 32 45 45 32 19.55634918 551 | 12 random-64-64-10.map 64 64 6 26 51 14 51.14213562 552 | 10 random-64-64-10.map 64 64 1 23 41 29 43.07106781 553 | 8 random-64-64-10.map 64 64 38 40 9 55 35.21320343 554 | 5 random-64-64-10.map 64 64 10 30 12 9 23.00000000 555 | 12 random-64-64-10.map 64 64 55 59 49 12 50.31370850 556 | 10 random-64-64-10.map 64 64 51 19 42 56 40.72792206 557 | 7 random-64-64-10.map 64 64 29 34 54 21 30.38477631 558 | 3 random-64-64-10.map 64 64 24 36 33 28 12.89949493 559 | 10 random-64-64-10.map 64 64 44 8 19 38 41.52691193 560 | 8 random-64-64-10.map 64 64 34 32 39 2 32.07106781 561 | 8 random-64-64-10.map 64 64 3 41 29 22 34.45584412 562 | 7 random-64-64-10.map 64 64 45 51 21 61 28.14213562 563 | 15 random-64-64-10.map 64 64 10 14 42 59 60.01219330 564 | 7 random-64-64-10.map 64 64 19 0 3 25 31.62741699 565 | 3 random-64-64-10.map 64 64 53 39 47 28 13.48528137 566 | 16 random-64-64-10.map 64 64 8 49 63 22 66.18376617 567 | 5 random-64-64-10.map 64 64 51 12 55 34 23.65685425 568 | 7 random-64-64-10.map 64 64 40 43 15 57 31.97056274 569 | 10 random-64-64-10.map 64 64 14 63 26 25 42.97056274 570 | 10 random-64-64-10.map 64 64 61 52 22 45 41.89949493 571 | 13 random-64-64-10.map 64 64 57 58 44 11 52.38477631 572 | 13 random-64-64-10.map 64 64 12 37 61 28 52.72792206 573 | 12 random-64-64-10.map 64 64 25 15 0 54 49.94112549 574 | 2 random-64-64-10.map 64 64 33 5 26 1 8.65685425 575 | 16 random-64-64-10.map 64 64 5 9 34 60 64.76955261 576 | 11 random-64-64-10.map 64 64 18 18 17 60 44.65685425 577 | 12 random-64-64-10.map 64 64 52 37 12 16 49.28427124 578 | 8 random-64-64-10.map 64 64 13 43 40 59 34.21320343 579 | 12 random-64-64-10.map 64 64 29 13 40 60 51.55634918 580 | 4 random-64-64-10.map 64 64 18 43 32 36 16.89949493 581 | 13 random-64-64-10.map 64 64 18 11 44 54 54.94112549 582 | 5 random-64-64-10.map 64 64 22 10 3 17 21.89949493 583 | 13 random-64-64-10.map 64 64 61 10 37 56 55.94112549 584 | 12 random-64-64-10.map 64 64 52 13 5 2 51.55634918 585 | 14 random-64-64-10.map 64 64 27 16 2 63 57.94112549 586 | 15 random-64-64-10.map 64 64 16 58 53 13 63.25483398 587 | 0 random-64-64-10.map 64 64 25 6 23 7 2.41421356 588 | 13 random-64-64-10.map 64 64 10 7 12 59 53.65685425 589 | 10 random-64-64-10.map 64 64 14 38 41 63 40.87005768 590 | 8 random-64-64-10.map 64 64 59 12 26 7 35.07106781 591 | 9 random-64-64-10.map 64 64 5 50 29 26 37.45584412 592 | 8 random-64-64-10.map 64 64 40 62 42 31 32.65685425 593 | 12 random-64-64-10.map 64 64 22 21 59 50 50.18376617 594 | 8 random-64-64-10.map 64 64 47 42 53 11 34.07106781 595 | 8 random-64-64-10.map 64 64 15 52 34 29 32.04163055 596 | 5 random-64-64-10.map 64 64 45 11 25 14 22.07106781 597 | 4 random-64-64-10.map 64 64 17 52 34 45 19.89949493 598 | 5 random-64-64-10.map 64 64 21 29 11 12 21.72792206 599 | 14 random-64-64-10.map 64 64 14 59 47 15 59.42640686 600 | 16 random-64-64-10.map 64 64 59 0 14 44 67.91168823 601 | 9 random-64-64-10.map 64 64 21 56 58 56 38.41421356 602 | 14 random-64-64-10.map 64 64 0 38 57 36 58.65685425 603 | 10 random-64-64-10.map 64 64 1 20 20 54 42.45584412 604 | 5 random-64-64-10.map 64 64 35 20 14 25 23.65685425 605 | 11 random-64-64-10.map 64 64 23 50 32 6 47.72792206 606 | 3 random-64-64-10.map 64 64 52 44 60 54 14.48528137 607 | 13 random-64-64-10.map 64 64 44 7 40 57 52.48528137 608 | 15 random-64-64-10.map 64 64 8 14 46 58 62.66904755 609 | 7 random-64-64-10.map 64 64 27 49 0 43 30.07106781 610 | 8 random-64-64-10.map 64 64 27 50 50 28 35.04163055 611 | 7 random-64-64-10.map 64 64 52 50 28 61 29.14213562 612 | 0 random-64-64-10.map 64 64 53 30 56 29 3.41421356 613 | 10 random-64-64-10.map 64 64 22 5 50 30 41.87005768 614 | 8 random-64-64-10.map 64 64 47 51 25 25 35.69848480 615 | 8 random-64-64-10.map 64 64 48 9 15 16 35.89949493 616 | 7 random-64-64-10.map 64 64 20 44 43 33 28.14213562 617 | 4 random-64-64-10.map 64 64 21 21 35 33 18.97056274 618 | 1 random-64-64-10.map 64 64 19 53 23 52 4.41421356 619 | 10 random-64-64-10.map 64 64 38 3 13 34 42.52691193 620 | 5 random-64-64-10.map 64 64 37 16 36 38 23.24264069 621 | 13 random-64-64-10.map 64 64 0 34 49 49 55.21320343 622 | 4 random-64-64-10.map 64 64 42 53 28 42 19.72792206 623 | 12 random-64-64-10.map 64 64 45 47 29 4 50.21320343 624 | 9 random-64-64-10.map 64 64 18 29 38 0 37.87005768 625 | 10 random-64-64-10.map 64 64 4 11 46 7 43.65685425 626 | 7 random-64-64-10.map 64 64 44 39 25 18 31.79898987 627 | 10 random-64-64-10.map 64 64 63 52 31 29 42.11269836 628 | 6 random-64-64-10.map 64 64 62 21 38 28 26.89949493 629 | 12 random-64-64-10.map 64 64 43 58 47 13 48.65685425 630 | 11 random-64-64-10.map 64 64 18 13 59 15 44.65685425 631 | 13 random-64-64-10.map 64 64 49 39 6 19 52.45584412 632 | 9 random-64-64-10.map 64 64 21 40 14 4 39.72792206 633 | 8 random-64-64-10.map 64 64 41 20 18 1 32.62741699 634 | 4 random-64-64-10.map 64 64 3 42 7 27 16.65685425 635 | 11 random-64-64-10.map 64 64 9 56 50 54 44.65685425 636 | 10 random-64-64-10.map 64 64 45 36 11 54 41.45584412 637 | 9 random-64-64-10.map 64 64 12 23 29 52 37.21320343 638 | 8 random-64-64-10.map 64 64 16 41 48 37 34.24264069 639 | 5 random-64-64-10.map 64 64 13 33 8 15 20.07106781 640 | 11 random-64-64-10.map 64 64 14 49 54 37 45.55634918 641 | 9 random-64-64-10.map 64 64 38 63 7 45 39.62741699 642 | 2 random-64-64-10.map 64 64 56 36 55 44 9.82842712 643 | 9 random-64-64-10.map 64 64 19 9 21 46 39.48528137 644 | 6 random-64-64-10.map 64 64 36 25 43 48 25.89949493 645 | 6 random-64-64-10.map 64 64 39 46 59 57 25.72792206 646 | 17 random-64-64-10.map 64 64 0 21 59 49 70.59797974 647 | 19 random-64-64-10.map 64 64 0 58 61 21 76.91168823 648 | 9 random-64-64-10.map 64 64 58 19 36 46 37.87005768 649 | 9 random-64-64-10.map 64 64 26 6 46 37 39.87005768 650 | 3 random-64-64-10.map 64 64 39 54 52 56 14.41421356 651 | 4 random-64-64-10.map 64 64 53 29 57 45 17.65685425 652 | 10 random-64-64-10.map 64 64 33 34 5 8 41.69848480 653 | 15 random-64-64-10.map 64 64 30 59 51 7 61.28427124 654 | 4 random-64-64-10.map 64 64 28 0 47 2 19.82842712 655 | 16 random-64-64-10.map 64 64 36 59 7 6 66.18376617 656 | 6 random-64-64-10.map 64 64 26 37 19 60 27.07106781 657 | 14 random-64-64-10.map 64 64 19 7 58 46 59.25483398 658 | 9 random-64-64-10.map 64 64 21 31 56 21 39.14213562 659 | 1 random-64-64-10.map 64 64 7 21 13 23 6.82842712 660 | 5 random-64-64-10.map 64 64 46 12 27 7 21.07106781 661 | 15 random-64-64-10.map 64 64 9 62 38 12 62.01219330 662 | 15 random-64-64-10.map 64 64 49 0 31 54 62.62741699 663 | 17 random-64-64-10.map 64 64 55 52 18 0 69.66904755 664 | 12 random-64-64-10.map 64 64 15 35 60 23 49.97056274 665 | 3 random-64-64-10.map 64 64 12 21 6 10 13.48528137 666 | 15 random-64-64-10.map 64 64 31 0 33 57 60.07106781 667 | 5 random-64-64-10.map 64 64 44 38 34 22 20.72792206 668 | 9 random-64-64-10.map 64 64 38 7 4 19 38.97056274 669 | 4 random-64-64-10.map 64 64 34 31 27 15 19.48528137 670 | 15 random-64-64-10.map 64 64 0 62 16 7 61.62741699 671 | 15 random-64-64-10.map 64 64 35 0 10 50 60.94112549 672 | 12 random-64-64-10.map 64 64 49 6 1 4 51.07106781 673 | 7 random-64-64-10.map 64 64 13 52 17 25 29.24264069 674 | 3 random-64-64-10.map 64 64 47 46 60 43 15.07106781 675 | 10 random-64-64-10.map 64 64 23 25 6 61 43.04163055 676 | 14 random-64-64-10.map 64 64 49 54 14 14 56.25483398 677 | 13 random-64-64-10.map 64 64 39 60 40 9 52.82842712 678 | 7 random-64-64-10.map 64 64 10 27 3 4 28.72792206 679 | 19 random-64-64-10.map 64 64 13 0 53 59 76.74011536 680 | 4 random-64-64-10.map 64 64 15 38 31 41 17.24264069 681 | 11 random-64-64-10.map 64 64 19 56 61 51 46.31370850 682 | 11 random-64-64-10.map 64 64 58 20 16 21 45.48528137 683 | 5 random-64-64-10.map 64 64 50 35 28 34 22.41421356 684 | 13 random-64-64-10.map 64 64 7 2 34 41 52.52691193 685 | 6 random-64-64-10.map 64 64 45 35 25 22 25.38477631 686 | 2 random-64-64-10.map 64 64 45 18 40 25 9.07106781 687 | 8 random-64-64-10.map 64 64 40 11 61 34 33.45584412 688 | 12 random-64-64-10.map 64 64 6 9 30 48 49.52691193 689 | 15 random-64-64-10.map 64 64 54 13 8 51 62.91168823 690 | 15 random-64-64-10.map 64 64 17 54 50 8 60.84062042 691 | 12 random-64-64-10.map 64 64 29 40 53 2 50.52691193 692 | 15 random-64-64-10.map 64 64 11 57 55 16 63.91168823 693 | 5 random-64-64-10.map 64 64 30 32 18 49 22.55634918 694 | 5 random-64-64-10.map 64 64 36 56 52 41 23.97056274 695 | 16 random-64-64-10.map 64 64 61 59 2 48 64.14213562 696 | 11 random-64-64-10.map 64 64 5 17 45 27 44.14213562 697 | 11 random-64-64-10.map 64 64 41 52 30 11 45.55634918 698 | 11 random-64-64-10.map 64 64 44 53 22 19 44.28427124 699 | 11 random-64-64-10.map 64 64 43 62 2 55 44.48528137 700 | 11 random-64-64-10.map 64 64 14 40 39 5 45.94112549 701 | 15 random-64-64-10.map 64 64 44 4 53 62 62.89949493 702 | 5 random-64-64-10.map 64 64 3 28 20 19 22.48528137 703 | 11 random-64-64-10.map 64 64 51 32 16 57 46.52691193 704 | 12 random-64-64-10.map 64 64 21 41 63 19 51.11269836 705 | 18 random-64-64-10.map 64 64 2 53 55 11 72.98275604 706 | 16 random-64-64-10.map 64 64 62 45 9 16 65.01219330 707 | 3 random-64-64-10.map 64 64 17 33 5 28 14.65685425 708 | 10 random-64-64-10.map 64 64 33 50 48 15 42.38477631 709 | 14 random-64-64-10.map 64 64 39 59 12 13 57.76955261 710 | 9 random-64-64-10.map 64 64 34 14 39 51 39.07106781 711 | 10 random-64-64-10.map 64 64 6 11 45 19 42.31370850 712 | 9 random-64-64-10.map 64 64 30 55 15 26 36.38477631 713 | 10 random-64-64-10.map 64 64 6 57 27 25 41.87005768 714 | 6 random-64-64-10.map 64 64 19 35 21 58 25.24264069 715 | 14 random-64-64-10.map 64 64 49 63 51 6 57.82842712 716 | 13 random-64-64-10.map 64 64 28 3 19 54 55.31370850 717 | 12 random-64-64-10.map 64 64 49 31 1 22 51.72792206 718 | 6 random-64-64-10.map 64 64 38 24 52 42 24.38477631 719 | 10 random-64-64-10.map 64 64 60 50 25 63 41.21320343 720 | 6 random-64-64-10.map 64 64 33 25 10 33 26.31370850 721 | 12 random-64-64-10.map 64 64 1 8 25 48 51.11269836 722 | 13 random-64-64-10.map 64 64 25 49 63 14 54.84062042 723 | 1 random-64-64-10.map 64 64 56 46 59 43 4.82842712 724 | 18 random-64-64-10.map 64 64 8 3 44 59 72.08326111 725 | 14 random-64-64-10.map 64 64 61 11 33 58 58.59797974 726 | 18 random-64-64-10.map 64 64 0 47 60 16 72.84062042 727 | 3 random-64-64-10.map 64 64 7 57 13 46 14.07106781 728 | 4 random-64-64-10.map 64 64 19 1 5 6 16.07106781 729 | 12 random-64-64-10.map 64 64 13 13 56 25 48.55634918 730 | 6 random-64-64-10.map 64 64 19 23 8 2 26.14213562 731 | 5 random-64-64-10.map 64 64 58 6 59 26 21.24264069 732 | 4 random-64-64-10.map 64 64 48 13 62 18 16.07106781 733 | 5 random-64-64-10.map 64 64 40 21 60 26 22.07106781 734 | 5 random-64-64-10.map 64 64 40 50 45 31 21.07106781 735 | 8 random-64-64-10.map 64 64 21 44 43 19 35.28427124 736 | 4 random-64-64-10.map 64 64 11 27 6 44 19.65685425 737 | 9 random-64-64-10.map 64 64 31 12 41 47 39.14213562 738 | 17 random-64-64-10.map 64 64 14 1 63 47 71.56854248 739 | 8 random-64-64-10.map 64 64 34 11 44 40 34.89949493 740 | 13 random-64-64-10.map 64 64 10 0 30 47 55.28427124 741 | 6 random-64-64-10.map 64 64 40 34 26 52 25.55634918 742 | 14 random-64-64-10.map 64 64 34 55 28 2 56.07106781 743 | 8 random-64-64-10.map 64 64 24 33 58 36 35.24264069 744 | 8 random-64-64-10.map 64 64 54 29 20 25 35.65685425 745 | 9 random-64-64-10.map 64 64 24 41 37 8 38.38477631 746 | 12 random-64-64-10.map 64 64 30 6 1 42 49.76955261 747 | 9 random-64-64-10.map 64 64 35 61 41 26 37.48528137 748 | 13 random-64-64-10.map 64 64 16 6 63 26 55.28427124 749 | 15 random-64-64-10.map 64 64 46 8 1 47 63.49747467 750 | 8 random-64-64-10.map 64 64 36 34 4 41 35.48528137 751 | 11 random-64-64-10.map 64 64 50 11 8 18 44.89949493 752 | 9 random-64-64-10.map 64 64 18 54 28 21 37.14213562 753 | 11 random-64-64-10.map 64 64 10 42 52 30 46.97056274 754 | 7 random-64-64-10.map 64 64 9 1 17 27 29.31370850 755 | 13 random-64-64-10.map 64 64 17 8 59 36 54.18376617 756 | 8 random-64-64-10.map 64 64 31 27 55 46 34.21320343 757 | 15 random-64-64-10.map 64 64 5 24 61 40 63.21320343 758 | 6 random-64-64-10.map 64 64 26 20 52 16 27.65685425 759 | 14 random-64-64-10.map 64 64 34 8 12 55 56.11269836 760 | 9 random-64-64-10.map 64 64 61 6 24 2 38.65685425 761 | 4 random-64-64-10.map 64 64 24 27 17 39 17.48528137 762 | 6 random-64-64-10.map 64 64 27 42 3 48 26.48528137 763 | 12 random-64-64-10.map 64 64 38 5 61 47 51.52691193 764 | 10 random-64-64-10.map 64 64 2 34 42 38 43.07106781 765 | 18 random-64-64-10.map 64 64 0 10 62 37 73.18376617 766 | 9 random-64-64-10.map 64 64 6 43 37 24 39.45584412 767 | 8 random-64-64-10.map 64 64 30 26 57 9 35.21320343 768 | 15 random-64-64-10.map 64 64 62 56 4 52 63.65685425 769 | 16 random-64-64-10.map 64 64 62 60 14 24 64.66904755 770 | 3 random-64-64-10.map 64 64 61 45 54 54 14.24264069 771 | 8 random-64-64-10.map 64 64 17 10 31 38 34.38477631 772 | 11 random-64-64-10.map 64 64 6 62 28 27 44.11269836 773 | 10 random-64-64-10.map 64 64 1 55 26 24 43.69848480 774 | 3 random-64-64-10.map 64 64 35 7 47 12 14.07106781 775 | 7 random-64-64-10.map 64 64 24 16 50 27 30.55634918 776 | 15 random-64-64-10.map 64 64 61 23 9 44 60.69848480 777 | 12 random-64-64-10.map 64 64 60 33 24 5 49.35533905 778 | 1 random-64-64-10.map 64 64 21 0 26 5 7.65685425 779 | 5 random-64-64-10.map 64 64 35 32 49 17 22.55634918 780 | 6 random-64-64-10.map 64 64 0 49 0 24 26.41421356 781 | 9 random-64-64-10.map 64 64 41 8 53 41 37.97056274 782 | 5 random-64-64-10.map 64 64 48 55 46 33 23.65685425 783 | 5 random-64-64-10.map 64 64 6 25 25 31 21.48528137 784 | 4 random-64-64-10.map 64 64 27 21 21 36 18.07106781 785 | 7 random-64-64-10.map 64 64 60 27 37 40 28.97056274 786 | 6 random-64-64-10.map 64 64 48 29 27 20 24.72792206 787 | 2 random-64-64-10.map 64 64 28 22 17 22 11.82842712 788 | 6 random-64-64-10.map 64 64 4 1 12 24 27.72792206 789 | 3 random-64-64-10.map 64 64 23 55 34 59 13.24264069 790 | 3 random-64-64-10.map 64 64 47 11 38 21 14.89949493 791 | 7 random-64-64-10.map 64 64 31 2 59 6 30.24264069 792 | 8 random-64-64-10.map 64 64 54 57 28 41 33.79898987 793 | 12 random-64-64-10.map 64 64 28 6 46 47 48.45584412 794 | 2 random-64-64-10.map 64 64 33 41 39 33 11.65685425 795 | 8 random-64-64-10.map 64 64 56 39 58 5 35.41421356 796 | 16 random-64-64-10.map 64 64 23 62 53 9 67.18376617 797 | 6 random-64-64-10.map 64 64 3 46 24 54 25.48528137 798 | 4 random-64-64-10.map 64 64 42 16 31 28 17.72792206 799 | 2 random-64-64-10.map 64 64 7 4 3 2 8.00000000 800 | 2 random-64-64-10.map 64 64 14 42 24 40 10.82842712 801 | 8 random-64-64-10.map 64 64 11 25 41 16 34.31370850 802 | 9 random-64-64-10.map 64 64 43 8 10 22 39.97056274 803 | 13 random-64-64-10.map 64 64 11 48 27 0 54.62741699 804 | 15 random-64-64-10.map 64 64 41 0 46 61 63.89949493 805 | 17 random-64-64-10.map 64 64 29 58 61 1 70.84062042 806 | 4 random-64-64-10.map 64 64 42 8 57 2 17.48528137 807 | 13 random-64-64-10.map 64 64 11 13 47 50 54.84062042 808 | 4 random-64-64-10.map 64 64 17 55 31 48 16.89949493 809 | 5 random-64-64-10.map 64 64 8 43 15 60 20.48528137 810 | 4 random-64-64-10.map 64 64 12 29 10 46 17.82842712 811 | 14 random-64-64-10.map 64 64 51 45 16 4 59.59797974 812 | 3 random-64-64-10.map 64 64 23 32 37 35 15.24264069 813 | 10 random-64-64-10.map 64 64 24 34 44 2 40.28427124 814 | 4 random-64-64-10.map 64 64 19 29 30 16 17.55634918 815 | 13 random-64-64-10.map 64 64 28 16 59 56 55.18376617 816 | 6 random-64-64-10.map 64 64 21 45 8 25 27.14213562 817 | 3 random-64-64-10.map 64 64 40 5 48 17 15.89949493 818 | 4 random-64-64-10.map 64 64 51 11 57 28 19.48528137 819 | 6 random-64-64-10.map 64 64 19 15 0 29 25.97056274 820 | 15 random-64-64-10.map 64 64 11 45 59 11 63.84062042 821 | 5 random-64-64-10.map 64 64 43 10 22 3 23.89949493 822 | 13 random-64-64-10.map 64 64 17 0 50 36 52.01219330 823 | 6 random-64-64-10.map 64 64 26 0 1 5 27.65685425 824 | 4 random-64-64-10.map 64 64 24 60 20 46 16.24264069 825 | 12 random-64-64-10.map 64 64 17 59 29 12 51.97056274 826 | 2 random-64-64-10.map 64 64 34 52 32 41 11.82842712 827 | 17 random-64-64-10.map 64 64 1 29 62 54 71.35533905 828 | 6 random-64-64-10.map 64 64 39 26 54 44 25.38477631 829 | 6 random-64-64-10.map 64 64 1 61 21 47 26.38477631 830 | 14 random-64-64-10.map 64 64 16 10 62 32 56.52691193 831 | 17 random-64-64-10.map 64 64 0 7 35 62 71.25483398 832 | 5 random-64-64-10.map 64 64 32 38 12 33 22.07106781 833 | 5 random-64-64-10.map 64 64 29 57 49 59 20.82842712 834 | 4 random-64-64-10.map 64 64 18 33 29 23 16.89949493 835 | 4 random-64-64-10.map 64 64 8 57 1 43 17.48528137 836 | 3 random-64-64-10.map 64 64 1 51 9 59 12.48528137 837 | 13 random-64-64-10.map 64 64 9 41 53 22 52.45584412 838 | 6 random-64-64-10.map 64 64 54 42 52 17 27.24264069 839 | 21 random-64-64-10.map 64 64 52 0 0 61 86.05382385 840 | 5 random-64-64-10.map 64 64 18 34 32 49 21.97056274 841 | 16 random-64-64-10.map 64 64 57 56 13 12 66.91168823 842 | 10 random-64-64-10.map 64 64 42 21 47 60 42.48528137 843 | 13 random-64-64-10.map 64 64 19 14 62 38 52.94112549 844 | 16 random-64-64-10.map 64 64 56 19 2 42 64.11269836 845 | 7 random-64-64-10.map 64 64 18 47 25 19 31.72792206 846 | 4 random-64-64-10.map 64 64 49 34 51 51 17.82842712 847 | 16 random-64-64-10.map 64 64 2 61 51 25 65.66904755 848 | 10 random-64-64-10.map 64 64 7 28 45 41 43.38477631 849 | 7 random-64-64-10.map 64 64 45 46 30 23 29.21320343 850 | 8 random-64-64-10.map 64 64 37 45 30 14 33.89949493 851 | 15 random-64-64-10.map 64 64 29 0 25 62 63.65685425 852 | 6 random-64-64-10.map 64 64 18 58 39 49 24.72792206 853 | 11 random-64-64-10.map 64 64 15 61 30 20 47.21320343 854 | 6 random-64-64-10.map 64 64 3 39 25 43 24.48528137 855 | 12 random-64-64-10.map 64 64 45 9 41 56 49.48528137 856 | 9 random-64-64-10.map 64 64 45 28 12 41 38.97056274 857 | 17 random-64-64-10.map 64 64 63 31 3 8 70.11269836 858 | 7 random-64-64-10.map 64 64 51 33 45 58 28.65685425 859 | 6 random-64-64-10.map 64 64 2 36 16 19 25.72792206 860 | 2 random-64-64-10.map 64 64 46 22 39 19 9.41421356 861 | 3 random-64-64-10.map 64 64 6 63 14 55 12.48528137 862 | 15 random-64-64-10.map 64 64 56 34 5 59 61.94112549 863 | 13 random-64-64-10.map 64 64 9 37 57 54 55.62741699 864 | 6 random-64-64-10.map 64 64 33 33 55 40 25.48528137 865 | 16 random-64-64-10.map 64 64 43 59 0 13 67.91168823 866 | 3 random-64-64-10.map 64 64 55 42 52 53 13.41421356 867 | 7 random-64-64-10.map 64 64 48 22 35 46 30.55634918 868 | 10 random-64-64-10.map 64 64 58 8 58 47 40.65685425 869 | 3 random-64-64-10.map 64 64 2 18 4 33 15.82842712 870 | 11 random-64-64-10.map 64 64 46 44 1 45 47.07106781 871 | 8 random-64-64-10.map 64 64 55 24 26 35 34.38477631 872 | 16 random-64-64-10.map 64 64 20 58 50 5 67.18376617 873 | 14 random-64-64-10.map 64 64 6 32 56 12 58.28427124 874 | 6 random-64-64-10.map 64 64 34 38 46 60 26.97056274 875 | 8 random-64-64-10.map 64 64 33 63 5 54 33.48528137 876 | 9 random-64-64-10.map 64 64 36 7 21 39 38.79898987 877 | 15 random-64-64-10.map 64 64 1 33 50 4 61.01219330 878 | 4 random-64-64-10.map 64 64 34 24 43 13 16.48528137 879 | 10 random-64-64-10.map 64 64 13 35 52 45 43.14213562 880 | 10 random-64-64-10.map 64 64 18 50 19 10 42.89949493 881 | 13 random-64-64-10.map 64 64 47 30 5 57 54.35533905 882 | 1 random-64-64-10.map 64 64 42 26 37 29 6.24264069 883 | 1 random-64-64-10.map 64 64 20 26 14 29 7.82842712 884 | 3 random-64-64-10.map 64 64 51 37 40 32 13.07106781 885 | 6 random-64-64-10.map 64 64 44 12 27 27 25.55634918 886 | 17 random-64-64-10.map 64 64 6 58 48 8 69.74011536 887 | 3 random-64-64-10.map 64 64 46 11 54 23 15.89949493 888 | 8 random-64-64-10.map 64 64 1 24 35 24 35.65685425 889 | 1 random-64-64-10.map 64 64 51 41 45 39 6.82842712 890 | 7 random-64-64-10.map 64 64 49 9 49 37 30.24264069 891 | 11 random-64-64-10.map 64 64 11 9 53 0 45.72792206 892 | 9 random-64-64-10.map 64 64 36 49 1 37 39.97056274 893 | 8 random-64-64-10.map 64 64 14 22 11 55 34.24264069 894 | 15 random-64-64-10.map 64 64 15 5 21 62 60.89949493 895 | 10 random-64-64-10.map 64 64 60 17 28 37 40.28427124 896 | 18 random-64-64-10.map 64 64 39 0 7 60 73.84062042 897 | 8 random-64-64-10.map 64 64 54 16 63 48 35.72792206 898 | 10 random-64-64-10.map 64 64 29 33 60 12 40.28427124 899 | 7 random-64-64-10.map 64 64 21 12 10 39 31.55634918 900 | 6 random-64-64-10.map 64 64 46 51 23 44 25.89949493 901 | 6 random-64-64-10.map 64 64 61 2 38 14 27.97056274 902 | 11 random-64-64-10.map 64 64 0 12 40 24 45.55634918 903 | 3 random-64-64-10.map 64 64 23 59 36 57 13.82842712 904 | 4 random-64-64-10.map 64 64 7 59 24 59 18.41421356 905 | 6 random-64-64-10.map 64 64 33 26 58 31 27.07106781 906 | 6 random-64-64-10.map 64 64 15 10 5 33 27.14213562 907 | 2 random-64-64-10.map 64 64 53 16 51 8 8.82842712 908 | 4 random-64-64-10.map 64 64 41 58 34 42 18.89949493 909 | 9 random-64-64-10.map 64 64 19 12 28 46 38.89949493 910 | 10 random-64-64-10.map 64 64 4 2 26 31 41.04163055 911 | 0 random-64-64-10.map 64 64 36 30 36 27 3.00000000 912 | 9 random-64-64-10.map 64 64 43 25 49 61 38.48528137 913 | 9 random-64-64-10.map 64 64 44 34 58 1 39.38477631 914 | 11 random-64-64-10.map 64 64 57 14 24 42 46.35533905 915 | 3 random-64-64-10.map 64 64 34 18 46 15 13.82842712 916 | 12 random-64-64-10.map 64 64 58 52 25 20 49.76955261 917 | 1 random-64-64-10.map 64 64 15 41 11 35 7.65685425 918 | 5 random-64-64-10.map 64 64 24 23 45 30 23.89949493 919 | 3 random-64-64-10.map 64 64 26 41 16 47 13.07106781 920 | 10 random-64-64-10.map 64 64 16 46 20 6 41.65685425 921 | 9 random-64-64-10.map 64 64 31 16 20 48 36.55634918 922 | 7 random-64-64-10.map 64 64 28 33 45 55 30.79898987 923 | 12 random-64-64-10.map 64 64 17 51 56 28 48.52691193 924 | 8 random-64-64-10.map 64 64 43 17 20 40 34.28427124 925 | 8 random-64-64-10.map 64 64 16 61 46 62 32.07106781 926 | 6 random-64-64-10.map 64 64 50 33 35 51 24.21320343 927 | 10 random-64-64-10.map 64 64 9 17 50 20 43.65685425 928 | 16 random-64-64-10.map 64 64 40 61 30 1 64.14213562 929 | 3 random-64-64-10.map 64 64 34 56 47 63 15.89949493 930 | 6 random-64-64-10.map 64 64 32 18 45 40 27.38477631 931 | 5 random-64-64-10.map 64 64 56 57 36 48 23.72792206 932 | 2 random-64-64-10.map 64 64 12 8 20 8 8.00000000 933 | 3 random-64-64-10.map 64 64 52 29 60 19 15.07106781 934 | 6 random-64-64-10.map 64 64 22 30 10 52 27.55634918 935 | 1 random-64-64-10.map 64 64 41 27 41 22 5.82842712 936 | 7 random-64-64-10.map 64 64 38 38 14 23 30.21320343 937 | 2 random-64-64-10.map 64 64 27 44 30 36 9.82842712 938 | 10 random-64-64-10.map 64 64 59 8 46 43 40.38477631 939 | 3 random-64-64-10.map 64 64 24 11 11 6 15.65685425 940 | 6 random-64-64-10.map 64 64 27 34 42 51 24.97056274 941 | 11 random-64-64-10.map 64 64 5 18 42 36 44.45584412 942 | 8 random-64-64-10.map 64 64 23 34 55 28 34.48528137 943 | 1 random-64-64-10.map 64 64 32 1 33 6 6.00000000 944 | 16 random-64-64-10.map 64 64 60 37 1 17 67.87005768 945 | 7 random-64-64-10.map 64 64 12 1 19 28 29.89949493 946 | 5 random-64-64-10.map 64 64 23 48 41 41 20.89949493 947 | 15 random-64-64-10.map 64 64 20 0 50 47 61.18376617 948 | 14 random-64-64-10.map 64 64 61 5 61 61 57.65685425 949 | 17 random-64-64-10.map 64 64 51 13 0 50 68.66904755 950 | 10 random-64-64-10.map 64 64 58 63 21 53 42.55634918 951 | 7 random-64-64-10.map 64 64 34 39 61 37 28.65685425 952 | 10 random-64-64-10.map 64 64 10 43 24 7 41.79898987 953 | 9 random-64-64-10.map 64 64 34 10 41 42 36.07106781 954 | 12 random-64-64-10.map 64 64 49 2 39 48 50.14213562 955 | 8 random-64-64-10.map 64 64 20 27 37 2 32.62741699 956 | 14 random-64-64-10.map 64 64 25 13 46 63 58.69848480 957 | 3 random-64-64-10.map 64 64 42 11 33 3 12.89949493 958 | 7 random-64-64-10.map 64 64 35 63 18 42 30.38477631 959 | 8 random-64-64-10.map 64 64 28 14 53 32 34.21320343 960 | 8 random-64-64-10.map 64 64 57 30 51 60 32.48528137 961 | 14 random-64-64-10.map 64 64 12 19 40 63 56.76955261 962 | 5 random-64-64-10.map 64 64 11 39 16 18 23.07106781 963 | 1 random-64-64-10.map 64 64 7 36 4 30 7.24264069 964 | 0 random-64-64-10.map 64 64 6 49 8 48 2.41421356 965 | 3 random-64-64-10.map 64 64 31 20 43 24 13.65685425 966 | 13 random-64-64-10.map 64 64 50 17 8 40 52.11269836 967 | 17 random-64-64-10.map 64 64 4 10 59 45 71.25483398 968 | 9 random-64-64-10.map 64 64 57 42 23 47 36.07106781 969 | 11 random-64-64-10.map 64 64 50 34 9 25 44.72792206 970 | 16 random-64-64-10.map 64 64 54 15 12 60 65.91168823 971 | 18 random-64-64-10.map 64 64 4 40 63 5 74.66904755 972 | 7 random-64-64-10.map 64 64 38 45 11 33 31.97056274 973 | 4 random-64-64-10.map 64 64 42 13 25 11 18.65685425 974 | 9 random-64-64-10.map 64 64 9 54 3 20 36.48528137 975 | 10 random-64-64-10.map 64 64 57 37 17 32 42.07106781 976 | 5 random-64-64-10.map 64 64 60 20 43 6 22.79898987 977 | 12 random-64-64-10.map 64 64 26 60 52 20 51.94112549 978 | 8 random-64-64-10.map 64 64 40 18 12 31 33.38477631 979 | 12 random-64-64-10.map 64 64 18 4 44 41 50.11269836 980 | 5 random-64-64-10.map 64 64 24 8 16 25 20.31370850 981 | 10 random-64-64-10.map 64 64 27 45 30 4 43.65685425 982 | 10 random-64-64-10.map 64 64 22 28 8 63 40.79898987 983 | 11 random-64-64-10.map 64 64 4 39 47 40 45.65685425 984 | 2 random-64-64-10.map 64 64 57 43 48 42 9.41421356 985 | 3 random-64-64-10.map 64 64 40 38 43 52 15.82842712 986 | 11 random-64-64-10.map 64 64 5 44 48 45 45.07106781 987 | 8 random-64-64-10.map 64 64 3 21 3 53 34.24264069 988 | 10 random-64-64-10.map 64 64 28 40 4 8 43.69848480 989 | 3 random-64-64-10.map 64 64 25 10 16 20 13.72792206 990 | 8 random-64-64-10.map 64 64 36 16 56 38 32.62741699 991 | 3 random-64-64-10.map 64 64 56 11 52 24 14.65685425 992 | 10 random-64-64-10.map 64 64 27 37 54 63 40.69848480 993 | 2 random-64-64-10.map 64 64 34 20 24 20 10.00000000 994 | 12 random-64-64-10.map 64 64 38 11 61 49 48.11269836 995 | 17 random-64-64-10.map 64 64 5 21 56 58 68.66904755 996 | 11 random-64-64-10.map 64 64 12 3 56 6 45.82842712 997 | 0 random-64-64-10.map 64 64 61 33 62 36 3.41421356 998 | 6 random-64-64-10.map 64 64 11 34 29 19 24.21320343 999 | 12 random-64-64-10.map 64 64 4 6 0 56 51.65685425 1000 | 14 random-64-64-10.map 64 64 27 9 57 53 58.18376617 1001 | 10 random-64-64-10.map 64 64 63 53 56 14 41.89949493 1002 | --------------------------------------------------------------------------------