C# 读取文本文件并从中创建多维数组
我想读取一个txt文件并创建一个多维int数组,格式如下: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
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