C# 读取文本文件并从中创建多维数组

C# 读取文本文件并从中创建多维数组,c#,.net,C#,.net,我想读取一个txt文件并创建一个多维int数组,格式如下: var graph = new[,] { // 0 1 2 3 4 5 6 7 8 9 10 11...n { 0, 0, 0, 0, 0, 0, 10, 0, 12, 0, 0, 0 }, // 0 { 0, 0, 0, 0, 20, 0, 0, 26, 0, 5, 0, 6 }, // 1

我想读取一个txt文件并创建一个多维int数组,格式如下:

var graph = new[,]
    {
        // 0   1   2   3   4   5   6   7   8   9  10  11...n
        { 0,  0,  0,  0,  0,  0, 10,  0, 12,  0,  0,  0 }, // 0
        { 0,  0,  0,  0, 20,  0,  0, 26,  0,  5,  0,  6 }, // 1
        { 0,  0,  0,  0,  0,  0,  0, 15, 14,  0,  0,  9 }, // 2
        { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0 }, // 3
        { 0, 20,  0,  0,  0,  5, 17,  0,  0,  0,  0, 11 }, // 4
        { 0,  0,  0,  0,  5,  0,  6,  0,  3,  0,  0, 33 }, // 5
        {10,  0,  0,  0, 17,  6,  0,  0,  0,  0,  0,  0 }, // 6
        { 0, 26, 15,  0,  0,  0,  0,  0,  0,  3,  0, 20 }, // 7
        {12,  0, 14,  0,  0,  3,  0,  0,  0,  0,  0,  0 }, // 8
        { 0,  5,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0 }, // 9
        { 0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0 }, // 10
        { 0,  6,  9,  0, 11, 33,  0, 20,  0,  0,  0,  0 }, // 11..n
  };
这应该表示图形中的节点,并且彼此之间没有距离。我的txt文件如下所示(图片和图形值不匹配):

第一个值是开始节点,第二个值是结束节点,第三个值应该是距离。 因此,表中行的索引是现有的开始节点,如果节点之间没有直接连接,则字段中的值应为0,或者如果存在直接连接,则应与txt文件保持距离。列的索引应为所有结束节点

我是这样开始的:

 using (var reader = new StreamReader(@"USA-road-d.CAL.gr"))
    {
        while (!reader.EndOfStream)
        {
            var lineCount = File.ReadLines(@"USA-road-d.CAL.gr").Count();
            var pre_graph = new int[lineCount];

            //initialize array with 0s
            Array.Clear(pre_graph, 0, pre_graph.Length);

            string new_line;

            while ((new_line = reader.ReadLine()) != null)
            {
                var values = new_line.Split(null);
                pre_graph[int.Parse(values[2])] = int.Parse(values[3]);
            }
        }
    }
var pre_graph=new int[lineCount]错误,因为有多条边。我只想将不同开始节点的计数作为数组长度

我不知道怎样才能得到这个。有人能帮忙吗

最后,我想用这个图来实现dijkstra算法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

public static class DijkstraWithoutQueue
{
    public static List<int> DijkstraAlgorithm(int[,] graph, int sourceNode, int destinationNode)
    {
        var n = graph.GetLength(0);

        var distance = new int[n];
        for (int i = 0; i < n; i++)
        {
            distance[i] = int.MaxValue;
        }

        distance[sourceNode] = 0;

        var used = new bool[n];
        var previous = new int?[n];

        while (true)
        {
            var minDistance = int.MaxValue;
            var minNode = 0;
            for (int i = 0; i < n; i++)
            {
                if (!used[i] && minDistance > distance[i])
                {
                    minDistance = distance[i];
                    minNode = i;
                }
            }

            if (minDistance == int.MaxValue)
            {
                break;
            }

            used[minNode] = true;

            for (int i = 0; i < n; i++)
            {
                if (graph[minNode, i] > 0)
                {
                    var shortestToMinNode = distance[minNode];
                    var distanceToNextNode = graph[minNode, i];

                    var totalDistance = shortestToMinNode + distanceToNextNode;

                    if (totalDistance < distance[i])
                    {
                        distance[i] = totalDistance;
                        previous[i] = minNode;
                    }
                }
            }
        }

        if (distance[destinationNode] == int.MaxValue)
        {
            return null;
        }

        var path = new LinkedList<int>();
        int? currentNode = destinationNode;
        while (currentNode != null)
        {
            path.AddFirst(currentNode.Value);
            currentNode = previous[currentNode.Value];
        }

        return path.ToList();
    }

    public static void Main()
    {


        var graph = new[,]
        {
            // 0   1   2   3   4   5   6   7   8   9  10  11
            { 0,  0,  0,  0,  0,  0, 10,  0, 12,  0,  0,  0 }, // 0
            { 0,  0,  0,  0, 20,  0,  0, 26,  0,  5,  0,  6 }, // 1
            { 0,  0,  0,  0,  0,  0,  0, 15, 14,  0,  0,  9 }, // 2
            { 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0 }, // 3
            { 0, 20,  0,  0,  0,  5, 17,  0,  0,  0,  0, 11 }, // 4
            { 0,  0,  0,  0,  5,  0,  6,  0,  3,  0,  0, 33 }, // 5
            {10,  0,  0,  0, 17,  6,  0,  0,  0,  0,  0,  0 }, // 6
            { 0, 26, 15,  0,  0,  0,  0,  0,  0,  3,  0, 20 }, // 7
            {12,  0, 14,  0,  0,  3,  0,  0,  0,  0,  0,  0 }, // 8
            { 0,  5,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0 }, // 9
            { 0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0 }, // 10
            { 0,  6,  9,  0, 11, 33,  0, 20,  0,  0,  0,  0 }, // 11
        };

        PrintPath(graph, 0, 2);
        PrintPath(graph, 0, 10);
        PrintPath(graph, 0, 11);
        PrintPath(graph, 0, 1);
    }

    public static void PrintPath(int[,] graph, int sourceNode, int destinationNode)
    {
        Console.Write(
            "Shortest path [{0} -> {1}]: ",
            sourceNode,
            destinationNode);

        var path = DijkstraWithoutQueue.DijkstraAlgorithm(graph, sourceNode, destinationNode);

        if (path == null)
        {
            Console.WriteLine("no path");
        }
        else
        {
            int pathLength = 0;
            for (int i = 0; i < path.Count - 1; i++)
            {
                pathLength += graph[path[i], path[i + 1]];
            }

            var formattedPath = string.Join("->", path);
            Console.WriteLine("{0} (length {1})", formattedPath, pathLength);
        }
    }
    }
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.IO;
公共静态类不带队列
{
公共静态列表Dijkstra算法(int[,]图,int sourceNode,int destinationNode)
{
var n=graph.GetLength(0);
var距离=新整数[n];
对于(int i=0;idistance[i])
{
距离=距离[i];
minNode=i;
}
}
如果(minDistance==int.MaxValue)
{
打破
}
used[minNode]=true;
对于(int i=0;i0)
{
var shortestToMinNode=距离[minNode];
var distanceToNextNode=图[minNode,i];
var totalDistance=最短到Innode+距离到ExtNode;
if(总距离<距离[i])
{
距离[i]=总距离;
前[i]=minNode;
}
}
}
}
if(距离[destinationNode]==int.MaxValue)
{
返回null;
}
var path=new LinkedList();
int?currentNode=目的节点;
while(currentNode!=null)
{
path.AddFirst(currentNode.Value);
currentNode=上一个[currentNode.Value];
}
返回路径ToList();
}
公共静态void Main()
{
变量图=新[,]
{
// 0   1   2   3   4   5   6   7   8   9  10  11
{ 0,  0,  0,  0,  0,  0, 10,  0, 12,  0,  0,  0 }, // 0
{ 0,  0,  0,  0, 20,  0,  0, 26,  0,  5,  0,  6 }, // 1
{ 0,  0,  0,  0,  0,  0,  0, 15, 14,  0,  0,  9 }, // 2
{ 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0 }, // 3
{ 0, 20,  0,  0,  0,  5, 17,  0,  0,  0,  0, 11 }, // 4
{ 0,  0,  0,  0,  5,  0,  6,  0,  3,  0,  0, 33 }, // 5
{10,  0,  0,  0, 17,  6,  0,  0,  0,  0,  0,  0 }, // 6
{ 0, 26, 15,  0,  0,  0,  0,  0,  0,  3,  0, 20 }, // 7
{12,  0, 14,  0,  0,  3,  0,  0,  0,  0,  0,  0 }, // 8
{ 0,  5,  0,  0,  0,  0,  0,  3,  0,  0,  0,  0 }, // 9
{ 0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0 }, // 10
{ 0,  6,  9,  0, 11, 33,  0, 20,  0,  0,  0,  0 }, // 11
};
打印路径(图,0,2);
打印路径(图,0,10);
打印路径(图,0,11);
打印路径(图,0,1);
}
公共静态void打印路径(int[,]图,int sourceNode,int destinationNode)
{
控制台,写(
“最短路径[{0}->{1}]:”,
sourceNode,
目的节点);
var path=dijkstrawhithoutqueue.dijkstra算法(图、源节点、目的节点);
if(路径==null)
{
Console.WriteLine(“无路径”);
}
其他的
{
int路径长度=0;
for(int i=0;i”,路径);
WriteLine(“{0}(长度{1})”,formattedPath,pathLength;
}
}
}

我在GitHub为您准备了一个解决方案

使用1890815x1890815矩阵的阵列联机不是一个好主意。 表示这样一个数组(1890815x1890815x4x2)大约需要28601450兆字节,或者您需要一个具有28PB内存的解决方案

我想您永远无法为美国路线图创建solid matrix,因为您可能需要大约1T的DDR内存(经过优化)或28 PB(包括零),我为您准备了Visual Studio解决方案(打开项目需要VS2019预览):

这也是一个好消息,如果不考虑28 PB的要求,您可以创建并使用连接矩阵(C#8.0)从文件加载数据,并在大约5秒内创建节点和边的树结构

5.6秒从存储器中的archieve加载所有美国道路,并验证结构

静态类程序
{
静态异步任务主(字符串[]args)
{
使用(var archive=ZipFile.OpenRead(args[0]))
{
var entry=archive.Entries.Where(=>..FullName.Equals(“USA-road-d.CAL.gr”),StringComparison.OrdinalIgnoreC