?? tsp.txt
字號:
目前,我用C#語言編寫的基于遺傳算法的旅行銷售員問題的程序再幾天就要完成了,部分代碼如下。
namespace TSP
{
//數(shù)據(jù)文件格式:
//第一行有兩個數(shù)據(jù):矩陣行數(shù) 矩陣列數(shù)
//接下來的行的數(shù)據(jù):行 列 該行該列的元素值
//注意數(shù)據(jù)與數(shù)據(jù)之間是用空格隔開的,沒有給出的矩陣的某些位置的值用0來代替
using System;
using System.IO;
class TestClass
{
private static Floyd test2=new Floyd();
public static void Test1()
{
double [,]Mat;
Mat=LSMat.LoadDoubleDataFile(@"d:\c#\data01.txt");
//顯示Mat
for(int i=0;i<=Mat.GetUpperBound(0);i++)
{
for(int j=0;j<=Mat.GetUpperBound(1);j++)
Console.Write("{0}\t",Mat[i,j]);
Console.Write("\n");
}
LSMat.SaveDataFile(@"d:\c#\datas01.txt",Mat);
}
public static void Test2(string DataFileName)
{
test2.MinFloyd(DataFileName);
Console.WriteLine("----------- 輸出結果 ----------");
for(int i=0;i for(int j=0;j {
Console.Write("{0}:\t",test2.GetDistance(i,j));
Console.WriteLine(test2.GetPath(i,j));
}
Console.WriteLine("------------- 結束 ------------");
}
public static void Main(string[] args)
{
//Test1(); //運行LSMat類的測試函數(shù)
//Test2(@"d:\c#\data01.txt");
int []t;
t=RandNumber.RandDifferInt(90);
for(int i=0;i {
Console.Write("{0} ",t[i]);
if(i%10==9) Console.Write("\n");
}
}
}
/* 下面是TSP問題的遺傳算法實現(xiàn)類
* */
class Ga
{
/*
private int N; //群體規(guī)模
private int Length; //個體長度
private double Pc; //交叉概率
private double Pm; //變異概率
private int MaxGene; //最大迭代代數(shù)
private int []MinIndividual; //當前代的最好個體指針
private double MinValue; //到當前代至最好個體的適應度值
private double [,]Buf1;
*/
}
class RandNumber
{
// 返回low與high之間的number個隨機整數(shù)(包括low和high)
public static int[] RandInt(int low,int high,int number)
{
Random rr=new Random();
int []randvec;
randvec=new int[number];
for(int i=0;i randvec[i]=rr.Next()%(high-low+1)+low;
return randvec;
}
// 返回low與high之間的number(number小于high-low+1)個不同的隨機整數(shù)(包括low和high)
public static int[] RandDifferInt(int low,int high,int number)
{
if(number>high-low+1) number=high-low+1;
Random rr=new Random();
int []randvec;
randvec=new int[number];
randvec[0]=rr.Next()%(high-low+1)+low;
int randi; //存儲中間過程產(chǎn)生的隨機整數(shù)
bool IsDiffer;//用于判斷新產(chǎn)生的隨機整數(shù)是否與以前產(chǎn)生的相同,若不同為真,否則為假
for(int i=1;i {
while(true)
{
randi=rr.Next()%(high-low+1)+low;
IsDiffer=true; //設定為真
for(int j=0;j {
if(randi==randvec[j])
{
IsDiffer=false; //相同為假
break;
}
}
if(IsDiffer)
{
randvec[i]=randi;
break;
}
}
}
return randvec;
}
// 返回low與high之間的high-low+1個不同的隨機整數(shù)(包括low和high)
public static int[] RandDifferInt(int low,int high)
{
return RandDifferInt(low,high,high-low+1);
}
// 返回0與high之間的high+1個不同的隨機整數(shù)(包括0和high)
public static int[] RandDifferInt(int high)
{
return RandDifferInt(0,high,high+1);
}
}
/* 下面是Floyd算法類
* */
class Floyd
{
private double [,]Distance; //圖的距離矩陣
private int [,]Path; //圖的最短路徑的緊前頂點矩陣
public int GetDotN() //獲得頂點數(shù)
{
return Path.GetLength(0);
}
public double GetDistance(int i,int j) //獲得頂點i到頂點j的最短距離
{
return Distance[i,j];
}
public string GetPath(int ni,int nj)
{
int []pathReverse;
pathReverse=new int[Path.GetLength(0)];
pathReverse[0]=Path[ni,nj];
int k=0;
while(pathReverse[k]!=ni)
{
k++;
pathReverse[k]=Path[ni,pathReverse[k-1]];
}
string path=pathReverse[k].ToString();
string str1="-->";
for(int i=k-1;i>=0;i--)
{
path+=(str1+pathReverse[i].ToString());
}
path+=(str1+nj.ToString());
return path;
}
public void MinFloyd(string DataFileName)
{
double [,]CostMat;
CostMat=LSMat.LoadDoubleDataFile(DataFileName);
MinFloyd(CostMat);
}
//Floyd算法的實現(xiàn)
//CostMat是圖的權值矩陣
public void MinFloyd(double [,]CostMat)
{
int nn;
nn=CostMat.GetLength(0); //獲得圖的頂點個數(shù)
for(int i=0;i for(int j=0;j {
if(CostMat[i,j]==0)
CostMat[i,j]=10e+100;
}
Distance=new double[nn,nn];
Path=new int[nn,nn];
//初始化Path,Distance
for(int i=0;i {
for(int j=0;j {
Path[i,j]=i;
Distance[i,j]=CostMat[i,j];
}
Distance[i,i]=0.0;
}
for(int k=0;k for(int i=0;i for(int j=0;j {
double a1,a2;
a1=Distance[i,j];
a2=Distance[i,k]+Distance[k,j];
if(a1>a2)
{
Distance[i,j]=a2;
Path[i,j]=Path[k,j];
}
}
}
}
class LSMat
{
//從數(shù)據(jù)文件中獲取二維矩陣
public static double[,] LoadDoubleDataFile(string DataFileName)
{
FileStream fs; //文件指針
fs=File.Open(DataFileName,FileMode.Open,FileAccess.Read); //以只讀方式打開數(shù)據(jù)文件
StreamReader r=new StreamReader(fs);//創(chuàng)建讀入流
string str;
str=r.ReadLine(); //讀入數(shù)據(jù)文件的第一行
double []rowcolv; //定義一維數(shù)組
rowcolv=StringToDouble(str); //把特定字符串轉換為一維數(shù)組
double [,]Mat; //定義二維數(shù)組
Mat=new double[(int)rowcolv[0],(int)rowcolv[1]]; //創(chuàng)建二維數(shù)組Mat
while(r.Peek()>-1) //當?shù)竭_數(shù)據(jù)文件尾時結束循環(huán)
{
str=r.ReadLine(); //讀入數(shù)據(jù)文件當前行字符串
rowcolv=StringToDouble(str);//把特定字符串轉換為一維數(shù)組
Mat[(int)rowcolv[0],(int)rowcolv[1]]=rowcolv[2]; //為二維數(shù)組賦值
}
fs.Close(); //關閉數(shù)據(jù)文件指針
return Mat; //返回二維數(shù)組
}
//從數(shù)據(jù)文件中獲取二維矩陣
public static int[,] LoadIntleDataFile(string DataFileName)
{
FileStream fs; //文件指針
fs=File.Open(DataFileName,FileMode.Open,FileAccess.Read); //以只讀方式打開數(shù)據(jù)文件
StreamReader r=new StreamReader(fs);//創(chuàng)建讀入流
string str;
str=r.ReadLine(); //讀入數(shù)據(jù)文件的第一行
int []rowcolv; //定義一維數(shù)組
rowcolv=StringToInt(str); //把特定字符串轉換為一維數(shù)組
int [,]Mat; //定義二維數(shù)組
Mat=new int[(int)rowcolv[0],(int)rowcolv[1]]; //創(chuàng)建二維數(shù)組Mat
while(r.Peek()>-1) //當?shù)竭_數(shù)據(jù)文件尾時結束循環(huán)
{
str=r.ReadLine(); //讀入數(shù)據(jù)文件當前行字符串
rowcolv=StringToInt(str);//把特定字符串轉換為一維數(shù)組
Mat[(int)rowcolv[0],(int)rowcolv[1]]=rowcolv[2]; //為二維數(shù)組賦值
}
fs.Close(); //關閉數(shù)據(jù)文件指針
return Mat; //返回二維數(shù)組
}
//把雙精度型數(shù)據(jù)矩陣存入指定文件中
public static void SaveDataFile(string DataFileName,double [,]Mat)
{
FileStream fs;//文件指針
fs=File.Open(DataFileName,FileMode.OpenOrCreate,FileAccess.Write);//創(chuàng)建并打開文件指針
StreamWriter w=new StreamWriter(fs);//創(chuàng)建寫入文件流
string str;//定義字符串
string str2=" ";//創(chuàng)建一個空格字符串
str=Mat.GetLength(0).ToString()+str2+Mat.GetLength(1);// 行和列字符串
w.WriteLine(str);//寫入該字符串
//把每個元素寫入文件
for(int i=Mat.GetLowerBound(0);i<=Mat.GetUpperBound(0);i++)
for(int j=Mat.GetLowerBound(1);j<=Mat.GetUpperBound(1);j++)
{
str=i.ToString()+str2+j.ToString()+str2+Mat[i,j].ToString();
w.WriteLine(str);
}
w.Close();//關閉寫文件流
}
//把整型數(shù)據(jù)矩陣存入指定文件中
public static void SaveDataFile(string DataFileName,int [,]Mat)
{
FileStream fs;//文件指針
fs=File.Open(DataFileName,FileMode.OpenOrCreate,FileAccess.Write);//創(chuàng)建并打開文件指針
StreamWriter w=new StreamWriter(fs);//創(chuàng)建寫入文件流
string str;//定義字符串
string str2=" ";//創(chuàng)建一個空格字符串
str=Mat.GetLength(0).ToString()+str2+Mat.GetLength(1);// 行和列字符串
w.WriteLine(str);//寫入該字符串
//把每個元素寫入文件
for(int i=Mat.GetLowerBound(0);i<=Mat.GetUpperBound(0);i++)
for(int j=Mat.GetLowerBound(1);j<=Mat.GetUpperBound(1);j++)
{
str=i.ToString()+str2+j.ToString()+str2+Mat[i,j].ToString();
w.WriteLine(str);
}
w.Close();//關閉寫文件流
}
private static double[] StringToDouble(string str)
{
double []Mat; //定義一維數(shù)組
Mat=new Double[3]; //創(chuàng)建一維數(shù)組
string str1=null; //創(chuàng)建空字符串
int index1=0; //創(chuàng)建一個整型數(shù)并賦0
if(str[0]==' ') //如果字符串的首字符為空
{
//本循環(huán)目的是找到第一個不為“空格”的字符的索引,并把它賦給index1
for(int i=1;i {
if(str[i]!=' ')
{
index1=i;
break;
}
}
}
//下面循環(huán)的目的是以空格為分界符找出所有子字符串,同時把這些子字符串轉換成雙精度浮點數(shù)
int k=0;//標志著目前的子字符串的序號,從0開始記數(shù)
for(int i=index1;i {
if(str[i]==' '||i>=(str.Length-1)) //如果第i個字符為“空格”或者已到字符串結尾
{
//如果已到字符串結尾并且該字符不為“空格”,則把最后的字符加到最后的子字符串中
if(i>=(str.Length-1)&&(str[i]!=' '))
str1+=str[i];
Mat[k]=double.Parse(str1);//轉換字符串為雙精度浮點數(shù)
if(i<(str.Length-1)) //如果未到字符串結尾
{
k++; //記數(shù)到下一個子字符串
str1=str1.Remove(0,str1.Length); //清空子字符串
//下面循環(huán)的目的是從當前子字符串結尾的“空格”開始直至找到下一個非“空格”字符的索引
//或者到字符串結尾(我們知道兩數(shù)據(jù)間可以有多個空格)
while(true)
{
if(str[i+1]!=' ') break;
i++;
if(i>=(str.Length-1)) break;
}
}
}
else
{
str1+=str[i];//繼續(xù)加入非“空格”字符到當前子字符串
}
}
return Mat; //返回字符串對應的一維數(shù)組
}
private static int[] StringToInt(string str)
{
int []Mat; //定義一維數(shù)組
Mat=new int[3]; //創(chuàng)建一維數(shù)組
string str1=null; //創(chuàng)建空字符串
int index1=0; //創(chuàng)建一個整型數(shù)并賦0
if(str[0]==' ') //如果字符串的首字符為空
{
//本循環(huán)目的是找到第一個不為“空格”的字符的索引,并把它賦給index1
for(int i=1;i {
if(str[i]!=' ')
{
index1=i;
break;
}
}
}
//下面循環(huán)的目的是以空格為分界符找出所有子字符串,同時把這些子字符串轉換成雙精度浮點數(shù)
int k=0;//標志著目前的子字符串的序號,從0開始記數(shù)
for(int i=index1;i {
if(str[i]==' '||i>=(str.Length-1)) //如果第i個字符為“空格”或者已到字符串結尾
{
//如果已到字符串結尾并且該字符不為“空格”,則把最后的字符加到最后的子字符串中
if(i>=(str.Length-1)&&(str[i]!=' '))
str1+=str[i];
Mat[k]=int.Parse(str1);//轉換字符串為雙精度浮點數(shù)
if(i<(str.Length-1)) //如果未到字符串結尾
{
k++; //記數(shù)到下一個子字符串
str1=str1.Remove(0,str1.Length); //清空子字符串
//下面循環(huán)的目的是從當前子字符串結尾的“空格”開始直至找到下一個非“空格”字符的索引
//或者到字符串結尾(我們知道兩數(shù)據(jù)間可以有多個空格)
while(true)
{
if(str[i+1]!=' ') break;
i++;
if(i>=(str.Length-1)) break;
}
}
}
else
{
str1+=str[i];//繼續(xù)加入非“空格”字符到當前子字符串
}
}
return Mat; //返回字符串對應的一維數(shù)組
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -