路径搜索算法中的Java与C#速度比较

路径搜索算法中的Java与C#速度比较,java,c#,algorithm,performance,Java,C#,Algorithm,Performance,首先,我不确定这是否是发布此问题的正确位置,因此如果我错了,请移动它。谢谢 我的任务是比较Java和C#中相同的算法性能。这个算法应该是一个*搜索,但我想我让它更像洪水,但它工作得很好,我不是来修复它的。首先,我将发布我在Java和C#中使用的代码,然后解释我得到了什么 由于问题的主体限制在30000个字符以内,并且我输入了更多字符,因此我不得不从Java和C#中删除函数readFile(),以使其适合 已更新 在Jim Mischel指出后,我将C#version中的哈希函数更新为Java中的

首先,我不确定这是否是发布此问题的正确位置,因此如果我错了,请移动它。谢谢

我的任务是比较Java和C#中相同的算法性能。这个算法应该是一个*搜索,但我想我让它更像洪水,但它工作得很好,我不是来修复它的。首先,我将发布我在Java和C#中使用的代码,然后解释我得到了什么

由于问题的主体限制在30000个字符以内,并且我输入了更多字符,因此我不得不从Java和C#中删除函数readFile(),以使其适合

已更新

在Jim Mischel指出后,我将C#version中的哈希函数更新为Java中的哈希函数,从而提高了性能

同样多亏了Matt Timmermans,我意识到我一直在调试中运行C#(这是因为我没有仔细考虑),并且为了发布更高的性能而改变

C#版本:

文件:Program.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;

namespace A_Star_Compare
{
    class Program
    {
        static int StartX = 0;
        static int StartY = 0;
        static int TargetX = 0;
        static int TargetY = 0;
        static int Width = 0;
        static int Height = 0;
        static TimeSpan TotalTime = TimeSpan.Zero;
        static double[] TrialTimes = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        static Dictionary<int, List<int>> Obstacles = new Dictionary<int, List<int>>();

        static void Main(string[] args)
        {
            for (int z = 0; z < 10; z++)
            {
                int Index = 0;
                Console.WriteLine("z: " + z);
                for (int x = 0; x < 14; x++)
                {
                    if (x < 10)
                        Index += 10;
                    else
                        Index += 100;

                    string Line = string.Empty;
                    string FileName = "Maps-" + Index + ".txt";
                    TotalTime = TimeSpan.Zero;
                    readFile(FileName);
                    TrialTimes[x] += (double)TotalTime.TotalSeconds / 100;
                }
            }

            int Index0 = 0;

            for (int i = 0; i < 14; i++)
            {
                if (i < 10)
                    Index0 += 10;
                else
                    Index0 += 100;

                string FileName = "Maps-" + Index0 + ".txt";

                Console.WriteLine("{0} Map size: {1}*{2}. On average map solved in: {3}", FileName, Index0, Index0, (double)TrialTimes[i] / 10);
            }
        }

        static void measureTime()
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();

            Algorithm Solve = new Algorithm(StartX, StartY, TargetX, TargetY, Width, Height, Obstacles);
            Solve.FullSolve();

            stopwatch.Stop();

            TotalTime += stopwatch.Elapsed;
        } 
    }
}
文件:Algorithm.java

package a.star_compare;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

public class Algorithm {

    private final HashMap<Integer, List<Integer>> obstacles;
    private final HashSet<Node> closedList;
    private final HashSet<Node> openList;
    private Node parent;
    private Node lowestCost;
    private final int startX;
    private final int startY;
    private final int targetX;
    private final int targetY;
    private final int width;
    private final int height;
    private boolean firstIter = true;

    public Algorithm(HashMap<Integer, List<Integer>> obs, int stX, int stY, int tgX, int tgY, int wid, int hei) {
        this.obstacles = new HashMap(obs);
        this.startX = stX;
        this.startY = stY;
        this.targetX = tgX;
        this.targetY = tgY;
        this.width = wid - 1;
        this.height = hei - 1;
        this.parent = new Node(startX, startY, 0, 0, 0, null);
        this.lowestCost = new Node(Integer.MAX_VALUE, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, 0, null);
        this.closedList = new HashSet<>();
        this.openList = new HashSet<>();
    }

    private boolean isBlockObstacle(Integer x, Integer y) {
        if (obstacles.containsKey(x) == false || (obstacles.containsKey(x) == true && obstacles.get(x).contains(y) == false)) {
            return false;
        }

        return true;
    }

    private void calculate(int h, int g, int f, int movedX, int movedY, Node addToList) {
        int h1 = 0;

        h = (targetX - movedX) * 10;

        if (h < 0) {
            h *= -1;
        }

        h1 = (targetY - movedY) * 10;

        if (h1 < 0) {
            h1 *= -1;
        }

        h += h1;
        f = g + h;

        addToList.f = f;
        addToList.h = h;
        addToList.pointsTo = parent;
    }

    private Node getNodeFromOpen(Node find) {
        Node ret = null;

        for (Node nfo : openList) {

            if (nfo.equals(find)) {
                ret = nfo;
                break;
            }

        }

        return ret;
    }

    private boolean checkNode(Node addToList, int g) {
        if (!openList.contains(addToList)) {
            openList.add(addToList);
            return true;
        } else {
            Node check = getNodeFromOpen(addToList);

            if (parent.g + g < check.g) {
                int offset = check.g - parent.g - g;

                check.g -= offset;
                check.f -= offset;
                check.pointsTo = parent;
            }
        }

        return false;
    }

    private void chooseNode() {
        for (Node nfo : openList) {
            if (nfo.x == targetX && nfo.y == targetY) {
                lowestCost = nfo;
                break;
            }

            if (nfo.f < lowestCost.f) {
                lowestCost = nfo;
            }
        }
    }

    private void countCost() {
        int[] directions = {1, -1};
        int[] diagnoly = {1, 1, -1, 1, 1, -1, -1, -1};
        int parentX = parent.x;
        int parentY = parent.y;
        int movedX = 0;
        int movedY = 0;
        int h = 0;
        int f = 0;
        Node addToList = null;

        //Left and right
        for (int i = 0; i < 2; i++) {
            //Check if it is possible to move right or left
            if (parentX + directions[i] <= width && parentX + directions[i] >= 0) {
                //Check if blocks to the right and left of parent aren't obstacles                   
                if (!isBlockObstacle(parentX + directions[i], parentY)) {
                    addToList = new Node(parentX + directions[i], parentY, parent.g + 10, 0, 0, null);

                    //Check if it is not on closed list
                    if (!closedList.contains(addToList)) {
                        movedX = addToList.x;
                        movedY = addToList.y;

                        calculate(h, addToList.g, f, movedX, movedY, addToList);
                        checkNode(addToList, 10);
                    }
                }
            }
        }

        //Up and down
        for (int i = 0; i < 2; i++) {
            //Check if possible to move up or down
            if (parentY + directions[i] <= height && parentY + directions[i] >= 0) {
                //Check if higher and lower block of parent aren't obstacles 
                if (!isBlockObstacle(parentX, parentY + directions[i])) {
                    addToList = new Node(parentX, parentY + directions[i], parent.g + 10, 0, 0, null);

                    if (!closedList.contains(addToList)) {
                        movedX = parentX;
                        movedY = parentY + directions[i];

                        calculate(h, addToList.g, f, movedX, movedY, addToList);
                        checkNode(addToList, 10);
                    }
                }
            }
        }

        //diagnoly
        for (int i = 0; i < 8; i += 2) {
            if (parentX + diagnoly[i] <= width && parentX + diagnoly[i] >= 0 && parentY + diagnoly[i + 1] <= height && parentY + diagnoly[i + 1] >= 0) {
                if (!isBlockObstacle(parentX + diagnoly[i], parentY + diagnoly[i + 1])) {
                    addToList = new Node(parentX + diagnoly[i], parentY + diagnoly[i + 1], parent.g + 14, 0, 0, null);

                    if (!closedList.contains(addToList)) {
                        movedX = parentX + diagnoly[i];
                        movedY = parentY + diagnoly[i + 1];

                        calculate(h, addToList.g, f, movedX, movedY, addToList);
                        checkNode(addToList, 14);
                    }
                }
            }
        }
    }

    public void FullSolve() {
        Node finalPath = null;

        if (firstIter) {
            countCost();
            chooseNode();
            openList.remove(parent);
            closedList.add(parent);
            parent = lowestCost;
            openList.remove(parent);
            closedList.add(parent);
            firstIter = false;

            FullSolve();
        } else {
            while (true) {
                if (openList.isEmpty()) {
                    break;
                }

                countCost();

                HashSet<Node> copy = new HashSet<>(openList);

                for (Node nfo : copy) {
                    parent = nfo;
                    countCost();
                    closedList.add(parent);
                    openList.remove(parent);

                    if (parent.x == targetX && parent.y == targetY) {
                        finalPath = parent;
                        break;
                    }
                }

                chooseNode();
                openList.remove(parent);
                closedList.add(parent);
                parent = lowestCost;

                lowestCost.f = Integer.MAX_VALUE;

                if (parent.x == targetX && parent.y == targetY) {
                    finalPath = parent;
                    break;
                }
            }        
        }
    }
}
包a.star\u比较;
导入java.util.HashMap;
导入java.util.HashSet;
导入java.util.List;
公共类算法{
私人最终哈希图障碍;
私有最终哈希集关闭列表;
私有最终哈希集openList;
私有节点父节点;
私有节点成本最低;
私人最终int startX;
私人终审法院;
targetX的私人决赛;
私人终审法院;
私有最终整数宽度;
私人最终整数高度;
私有布尔值firstIter=true;
公共算法(HashMap obs、int stX、int stY、int tgX、int tgY、int wid、int hei){
this.barriends=新哈希映射(obs);
this.startX=stX;
this.startY=stY;
this.targetX=tgX;
this.targetY=tgY;
该宽度=wid-1;
这个高度=hei-1;
this.parent=新节点(startX、startY、0、0、null);
this.lowestCost=新节点(Integer.MAX\u值,Integer.MAX\u值,0,Integer.MAX\u值,0,null);
this.closedList=new HashSet();
this.openList=new HashSet();
}
私有布尔值(整数x,整数y){
if(障碍物.containsKey(x)==false | |(障碍物.containsKey(x)==true和障碍物.get(x).contains(y)==false)){
返回false;
}
返回true;
}
私有void计算(int h、int g、int f、int movedX、int movedY、Node addToList){
int h1=0;
h=(targetX-movedX)*10;
if(h<0){
h*=-1;
}
h1=(targetY-movedY)*10;
如果(h1<0){
h1*=-1;
}
h+=h1;
f=g+h;
addToList.f=f;
addToList.h=h;
addToList.pointsTo=父级;
}
私有节点getNodeFromOpen(节点查找){
节点ret=null;
对于(节点nfo:openList){
如果(信息等于(查找)){
ret=nfo;
打破
}
}
返回ret;
}
私有布尔校验节点(节点addToList,int g){
如果(!openList.contains(addToList)){
openList.add(addToList);
返回true;
}否则{
节点检查=getNodeFromOpen(addToList);
如果(父.g+gpackage a.star_compare;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang3.time.StopWatch;

public class AStar_Compare {

    static double totalTime;
    static double[] trialTimes = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    static int startX;
    static int startY;
    static int targetX;
    static int targetY;
    static int width;
    static int heigth;
    static HashMap<Integer, List<Integer>> obstacles = new HashMap<>();
    static NumberFormat formatter = new DecimalFormat("#0.000000000");

    public static void main(String[] args) throws FileNotFoundException, IOException {

        for (int z = 0; z < 10; z++) {
            int Index = 0;
            System.out.println("z: " + z);
            for (int x = 0; x < 5; x++) {
                if (x < 10) {
                    Index += 10;
                } else {
                    Index += 100;
                }

                String fileName = "Maps-" + Index + ".txt";

                totalTime = 0;
                readFile(fileName);
                trialTimes[x] += totalTime / 1E9 / 100;
            }
        }

        int index0 = 0;

        for (int i = 0; i < 14; i++) {
            if (i < 10) {
                index0 += 10;
            } else {
                index0 += 100;
            }
            trialTimes[i] /= 10;
            String fileName = "Maps-" + index0 + ".txt";

            System.out.println(fileName + " Map size: " + index0 + "*" + index0 + ". On average map solved in: " + formatter.format(trialTimes[i]));
        }
    }

    static void measureTime() {
        StopWatch time = new StopWatch();

        time.start();

        Algorithm solve = new Algorithm(obstacles, startX, startY, targetX, targetY, width, heigth);
        solve.FullSolve();

        time.stop();

        totalTime += time.getNanoTime();
    }

}
package a.star_compare;

public class Node {
    public int x;
    public int y;
    public int g;
    public int h;
    public int f;

    public Node pointsTo;

    public Node(int gx, int gy, int gg, int gh, int gf, Node point){
        this.x = gx;
        this.y = gy;
        this.g = gg;
        this.h = gh;
        this.f = gf;
        this.pointsTo = point;
    }

    @Override
    public boolean equals(Object other){
        if(other == null) return false;
        if(other == this) return true;
        if(!(other instanceof Node)) return false;

        Node rhs = (Node)other;

        return this.x == rhs.x && this.y == rhs.y;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 83 * hash + this.x;
        hash = 83 * hash + this.y;
        return hash;
    }
}
package a.star_compare;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

public class Algorithm {

    private final HashMap<Integer, List<Integer>> obstacles;
    private final HashSet<Node> closedList;
    private final HashSet<Node> openList;
    private Node parent;
    private Node lowestCost;
    private final int startX;
    private final int startY;
    private final int targetX;
    private final int targetY;
    private final int width;
    private final int height;
    private boolean firstIter = true;

    public Algorithm(HashMap<Integer, List<Integer>> obs, int stX, int stY, int tgX, int tgY, int wid, int hei) {
        this.obstacles = new HashMap(obs);
        this.startX = stX;
        this.startY = stY;
        this.targetX = tgX;
        this.targetY = tgY;
        this.width = wid - 1;
        this.height = hei - 1;
        this.parent = new Node(startX, startY, 0, 0, 0, null);
        this.lowestCost = new Node(Integer.MAX_VALUE, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, 0, null);
        this.closedList = new HashSet<>();
        this.openList = new HashSet<>();
    }

    private boolean isBlockObstacle(Integer x, Integer y) {
        if (obstacles.containsKey(x) == false || (obstacles.containsKey(x) == true && obstacles.get(x).contains(y) == false)) {
            return false;
        }

        return true;
    }

    private void calculate(int h, int g, int f, int movedX, int movedY, Node addToList) {
        int h1 = 0;

        h = (targetX - movedX) * 10;

        if (h < 0) {
            h *= -1;
        }

        h1 = (targetY - movedY) * 10;

        if (h1 < 0) {
            h1 *= -1;
        }

        h += h1;
        f = g + h;

        addToList.f = f;
        addToList.h = h;
        addToList.pointsTo = parent;
    }

    private Node getNodeFromOpen(Node find) {
        Node ret = null;

        for (Node nfo : openList) {

            if (nfo.equals(find)) {
                ret = nfo;
                break;
            }

        }

        return ret;
    }

    private boolean checkNode(Node addToList, int g) {
        if (!openList.contains(addToList)) {
            openList.add(addToList);
            return true;
        } else {
            Node check = getNodeFromOpen(addToList);

            if (parent.g + g < check.g) {
                int offset = check.g - parent.g - g;

                check.g -= offset;
                check.f -= offset;
                check.pointsTo = parent;
            }
        }

        return false;
    }

    private void chooseNode() {
        for (Node nfo : openList) {
            if (nfo.x == targetX && nfo.y == targetY) {
                lowestCost = nfo;
                break;
            }

            if (nfo.f < lowestCost.f) {
                lowestCost = nfo;
            }
        }
    }

    private void countCost() {
        int[] directions = {1, -1};
        int[] diagnoly = {1, 1, -1, 1, 1, -1, -1, -1};
        int parentX = parent.x;
        int parentY = parent.y;
        int movedX = 0;
        int movedY = 0;
        int h = 0;
        int f = 0;
        Node addToList = null;

        //Left and right
        for (int i = 0; i < 2; i++) {
            //Check if it is possible to move right or left
            if (parentX + directions[i] <= width && parentX + directions[i] >= 0) {
                //Check if blocks to the right and left of parent aren't obstacles                   
                if (!isBlockObstacle(parentX + directions[i], parentY)) {
                    addToList = new Node(parentX + directions[i], parentY, parent.g + 10, 0, 0, null);

                    //Check if it is not on closed list
                    if (!closedList.contains(addToList)) {
                        movedX = addToList.x;
                        movedY = addToList.y;

                        calculate(h, addToList.g, f, movedX, movedY, addToList);
                        checkNode(addToList, 10);
                    }
                }
            }
        }

        //Up and down
        for (int i = 0; i < 2; i++) {
            //Check if possible to move up or down
            if (parentY + directions[i] <= height && parentY + directions[i] >= 0) {
                //Check if higher and lower block of parent aren't obstacles 
                if (!isBlockObstacle(parentX, parentY + directions[i])) {
                    addToList = new Node(parentX, parentY + directions[i], parent.g + 10, 0, 0, null);

                    if (!closedList.contains(addToList)) {
                        movedX = parentX;
                        movedY = parentY + directions[i];

                        calculate(h, addToList.g, f, movedX, movedY, addToList);
                        checkNode(addToList, 10);
                    }
                }
            }
        }

        //diagnoly
        for (int i = 0; i < 8; i += 2) {
            if (parentX + diagnoly[i] <= width && parentX + diagnoly[i] >= 0 && parentY + diagnoly[i + 1] <= height && parentY + diagnoly[i + 1] >= 0) {
                if (!isBlockObstacle(parentX + diagnoly[i], parentY + diagnoly[i + 1])) {
                    addToList = new Node(parentX + diagnoly[i], parentY + diagnoly[i + 1], parent.g + 14, 0, 0, null);

                    if (!closedList.contains(addToList)) {
                        movedX = parentX + diagnoly[i];
                        movedY = parentY + diagnoly[i + 1];

                        calculate(h, addToList.g, f, movedX, movedY, addToList);
                        checkNode(addToList, 14);
                    }
                }
            }
        }
    }

    public void FullSolve() {
        Node finalPath = null;

        if (firstIter) {
            countCost();
            chooseNode();
            openList.remove(parent);
            closedList.add(parent);
            parent = lowestCost;
            openList.remove(parent);
            closedList.add(parent);
            firstIter = false;

            FullSolve();
        } else {
            while (true) {
                if (openList.isEmpty()) {
                    break;
                }

                countCost();

                HashSet<Node> copy = new HashSet<>(openList);

                for (Node nfo : copy) {
                    parent = nfo;
                    countCost();
                    closedList.add(parent);
                    openList.remove(parent);

                    if (parent.x == targetX && parent.y == targetY) {
                        finalPath = parent;
                        break;
                    }
                }

                chooseNode();
                openList.remove(parent);
                closedList.add(parent);
                parent = lowestCost;

                lowestCost.f = Integer.MAX_VALUE;

                if (parent.x == targetX && parent.y == targetY) {
                    finalPath = parent;
                    break;
                }
            }        
        }
    }
}