M
Michele
Please forgive me for the neverending code down here but I cannot find a
rational explanation of the output of this simple program (really!).
Soluzione class has a double[,] field to represent a matrix. A method
named init() fills this matrix with random numbers. The main constructor
requires an int param (fCosto) which is _not_used_ inside init(). Every
time I instantiate a Soluzione object the matrix is filled by init().
The incredible thing is that if I create more than 9 objects where fCosto
= 3, there is always at least one of them whose matrix contains absurd
values! This does _not_ happen for objects constructed passing 1,2 or 4!
Any suggestions?
I compile with .NET 1.1 SP1 fully patched.
Thanks in advance!
Michael
------------------------------------------------------------------------------------
using System;
using TransGene;
using System.Collections;
namespace Test
{
class Tester: IComparer
{
[STAThread]
static void Main(string[] args)
{
Tester t = new Tester();
int[] prod = {5,5,20,15,15};
int[] req = {8,8,8,8,8,20};
int tot = 10;
Soluzione[] p1 = new Soluzione[tot];
Soluzione[] p2 = new Soluzione[tot];
for (int i = 0; i < p1.Length; i++) {
p1 = new Soluzione(prod, req, 3);
p2 = new Soluzione(prod, req, 1);
}
Array.Sort(p1,t);
Array.Sort(p2,t);
Console.WriteLine("Fitness "+p1[0].GetFCosto()
+"="+ p1[0].Fitness());
Console.Write(p1[0]);
Console.WriteLine("Fitness "+p2[0].GetFCosto()
+"="+ p2[0].Fitness());
Console.Write(p2[0]);
Console.ReadLine();
}
public int Compare(object o1, object o2) {
Soluzione x = (Soluzione) o1;
Soluzione y = (Soluzione) o2;
// ordino in modo decrescente
return x.Confronta(y);
}
}
}
--------------------------------------------------------------------------------------------
using System;
namespace TransGene
{
public class Soluzione {
private double[,] u;
private int nS;
private int nD;
private int[] prod;
private int[] req;
private int fCosto;
private static Random rand = new Random();
public Soluzione(int[] prod, int[] req, int fCosto) {
nS = prod.Length;
nD = req.Length;
this.req = req;
this.prod = prod;
this.fCosto= fCosto;
u = new double[nS,nD];
this.Init();
}
public Soluzione(Soluzione x) {
nS = x.nS;
nD = x.nD;
req = x.req;
prod = x.prod;
fCosto = x.fCosto;
u = new double[nS,nD];
this.Init();
}
private Soluzione() {
/* costruttore vuoto:
*
* - variabili a 0
* - oggetti a null */
}
public static Soluzione Vuota(Soluzione x) {
Soluzione v = new Soluzione();
v.nS = x.nS;
v.nD = x.nD;
v.req = x.req;
v.prod = x.prod;
v.fCosto = x.fCosto;
v.u = new double[v.nS,v.nD];
return v;
}
private void Init() {
/*Inizializzazione casuale della matrice.
Eseguo nS*nD posizionamenti casuali e
un aggiustamento finale.*/
/* indice di riga (sorgente) */
int si;
/* indice di colonna (destinazione) */
int dj;
/* output corrente della sorgente i */
double sumProdIJ;
/* input corrente della destinazione j*/
double sumReqIJ;
double delta;
double alpha;
for (int c = 0; c < nD*nS; c++) {
si = rand.Next(nS);
dj = rand.Next(nD);
sumProdIJ = 0;
for (int d = 0; d < nD; d++) sumProdIJ += u[si,d];
sumReqIJ = 0;
for (int s = 0; s < nS; s++) sumReqIJ += u[s,dj];
delta = Math.Min(prod[si]-sumProdIJ, req[dj]-sumReqIJ);
alpha = rand.NextDouble();
u[si,dj] += (alpha*delta);
}
/* aggiustamento*/
for (si = 0; si < nS; si++)
for (dj = 0; dj < nD; dj++) {
sumProdIJ = 0;
for (int d = 0; d < nD; d++) sumProdIJ += u[si,d];
sumReqIJ = 0;
for (int s = 0; s < nS; s++) sumReqIJ += u[s,dj];
delta = Math.Min(prod[si]-sumProdIJ, req[dj]-sumReqIJ);
u[si,dj] += delta;
}
}
public double[,] GetU() {
return u;
}
public int GetNS() {
return nS;
}
public int GetND() {
return nD;
}
public Soluzione Clona() {
Soluzione clone = new Soluzione(this);
clone.u = (double[,])this.u.Clone();
return clone;
}
public double Fitness () {
double costo = 0;
double cIJ = 0;
for (int si = 0; si < nS; si++)
for (int dj = 0; dj < nD; dj++) {
switch (fCosto) {
case 1:
cIJ = Math.Pow((Math.Abs(si-dj)+1),2)*u[si,dj];
break;
case 2:
cIJ =
Math.Pow((Math.Abs(si-dj)+1),2)*Math.Pow(u[si,dj], 2);
break;
case 3:
cIJ =
Math.Abs(si*dj-11)*Math.Sqrt(u[si,dj])+Math.Sqrt(u[si,dj]);
break;
case 4:
cIJ = Math.Abs(si*dj-11)*Math.Pow(u[si,dj],
2)+Math.Pow(u[si,dj], 4);
break;
default:
break;
}
costo += cIJ;
}
return costo;
}
public double Merce() {
double merce = 0;
for (int si = 0; si < nS; si++)
for (int dj = 0; dj < nD; dj++)
merce += u[si,dj];
return merce;
}
public Soluzione Muta() {
Soluzione z = this.Clona();
// scelgo a caso un elemento
int si = rand.Next(z.nS);
int dj = rand.Next(z.nD);
double[,] uZ = z.u;
// a caso lo setto al min (0) o al max
uZ[si,dj] = rand.NextDouble() >= 0.5 ? 0 :
Math.Min(prod[si],req[dj]);
// aggiusto la soluzione
for (si = 0; si < z.nS; si++)
for (dj = 0; dj < z.nD; dj++) {
double sumProdIJ = 0;
for (int d = 0; d < z.nD; d++)
sumProdIJ += uZ[si,d];
double sumReqIJ = 0;
for (int s = 0; s < z.nS; s++)
sumReqIJ += uZ[s,dj];
double delta = Math.Min(prod[si]-sumProdIJ,
req[dj]-sumReqIJ);
// alpha = 1 sottinteso
uZ[si,dj] = Math.Max(uZ[si,dj]+delta, 0);
}
return z;
}
public int[] GetProd() {
return prod;
}
public int[] GetReq() {
return req;
}
public int GetFCosto() {
return fCosto;
}
// rimpiazzare con CompareTo
public int Confronta(Soluzione x) {
return this.Fitness().CompareTo(x.Fitness());
}
public bool Uguale(Soluzione x) {
bool uguali = true;
for (int i = 0; i < nS && uguali; i++)
for (int j = 0; j < nD && uguali; j++)
uguali = u[i,j] == x.u[i,j];
return uguali;
}
public override string ToString() {
string s = "";
for (int i = 0; i < nS; i++) {
for (int j = 0; j < nD; j++) {
// s += Math.Round(u[i,j],2).ToString("0.00") + "\t";
s += "u["+i+","+j+"] ="+u[i,j] + "\n";
}
s+="\n";
}
s+="\n";
return s;
}
}
}
----------------------------------------------------------------------------------------------
This is the output
----------------------------------------------------------------------------------------------
Fitness 3=Non un numero reale (that is 'not a number' in Italian)
u[0,0] =0,645759544586035
u[0,1] =0
u[0,2] =0,0175906380334083
u[0,3] =0,349247457857778
u[0,4] =0,0210873891839998
u[0,5] =3,96631497033878
u[1,0] =0,286085618731453
u[1,1] =0,372272107842662
u[1,2] =1,2791667337149
u[1,3] =2,25893076399279
u[1,4] =0,0900398541882886
u[1,5] =0,71350492152991
u[2,0] =3,52830816941484
u[2,1] =5,272095936
u[2,2] =4,32616900310448
u[2,3] =4,57385969305198
u[2,4] =8,75662771182562E-06
u[2,5] =2,29955844180099
u[3,0] =2,10553080996468
u[3,1] =2,26539317651639
u[3,2] =0
u[3,3] =-1,77635683940025E-15 ----> it is negative! absurd!
u[3,4] =0
u[3,5] =10,6290760135189
u[4,0] =1,43431585730299
u[4,1] =0,0902387796409421
u[4,2] =2,37707362514721
u[4,3] =0,817962085097459
u[4,4] =7,888864
u[4,5] =2,39154565281139
Fitness 1=383,121099950505
u[0,0] =4,7550011217406
u[0,1] =0,241038878259402
u[0,2] =0,00395999999999999
u[0,3] =0
u[0,4] =0
u[0,5] =0
u[1,0] =3,0289
u[1,1] =0,5442669362372
u[1,2] =0,910992251562801
u[1,3] =0,366624599999999
u[1,4] =0,1492162122
u[1,5] =0
u[2,0] =0,190926198835202
u[2,1] =1,84422971053786
u[2,2] =3,5556601809682
u[2,3] =0,00214166337232413
u[2,4] =0,031324627313322
u[2,5] =14,3757176189731
u[3,0] =0
u[3,1] =5,192
u[3,2] =3,529387567469
u[3,3] =5,51189017097053
u[3,4] =0,0236308592012779
u[3,5] =0,743091402359193
u[4,0] =0,0251726794242
u[4,1] =0,178464474965537
u[4,2] =0
u[4,3] =2,11934356565715
u[4,4] =7,7958283012854
u[4,5] =4,88119097866772
-----------------------------------------------------------------------------------------------
rational explanation of the output of this simple program (really!).
Soluzione class has a double[,] field to represent a matrix. A method
named init() fills this matrix with random numbers. The main constructor
requires an int param (fCosto) which is _not_used_ inside init(). Every
time I instantiate a Soluzione object the matrix is filled by init().
The incredible thing is that if I create more than 9 objects where fCosto
= 3, there is always at least one of them whose matrix contains absurd
values! This does _not_ happen for objects constructed passing 1,2 or 4!
Any suggestions?
I compile with .NET 1.1 SP1 fully patched.
Thanks in advance!
Michael
------------------------------------------------------------------------------------
using System;
using TransGene;
using System.Collections;
namespace Test
{
class Tester: IComparer
{
[STAThread]
static void Main(string[] args)
{
Tester t = new Tester();
int[] prod = {5,5,20,15,15};
int[] req = {8,8,8,8,8,20};
int tot = 10;
Soluzione[] p1 = new Soluzione[tot];
Soluzione[] p2 = new Soluzione[tot];
for (int i = 0; i < p1.Length; i++) {
p1 = new Soluzione(prod, req, 3);
p2 = new Soluzione(prod, req, 1);
}
Array.Sort(p1,t);
Array.Sort(p2,t);
Console.WriteLine("Fitness "+p1[0].GetFCosto()
+"="+ p1[0].Fitness());
Console.Write(p1[0]);
Console.WriteLine("Fitness "+p2[0].GetFCosto()
+"="+ p2[0].Fitness());
Console.Write(p2[0]);
Console.ReadLine();
}
public int Compare(object o1, object o2) {
Soluzione x = (Soluzione) o1;
Soluzione y = (Soluzione) o2;
// ordino in modo decrescente
return x.Confronta(y);
}
}
}
--------------------------------------------------------------------------------------------
using System;
namespace TransGene
{
public class Soluzione {
private double[,] u;
private int nS;
private int nD;
private int[] prod;
private int[] req;
private int fCosto;
private static Random rand = new Random();
public Soluzione(int[] prod, int[] req, int fCosto) {
nS = prod.Length;
nD = req.Length;
this.req = req;
this.prod = prod;
this.fCosto= fCosto;
u = new double[nS,nD];
this.Init();
}
public Soluzione(Soluzione x) {
nS = x.nS;
nD = x.nD;
req = x.req;
prod = x.prod;
fCosto = x.fCosto;
u = new double[nS,nD];
this.Init();
}
private Soluzione() {
/* costruttore vuoto:
*
* - variabili a 0
* - oggetti a null */
}
public static Soluzione Vuota(Soluzione x) {
Soluzione v = new Soluzione();
v.nS = x.nS;
v.nD = x.nD;
v.req = x.req;
v.prod = x.prod;
v.fCosto = x.fCosto;
v.u = new double[v.nS,v.nD];
return v;
}
private void Init() {
/*Inizializzazione casuale della matrice.
Eseguo nS*nD posizionamenti casuali e
un aggiustamento finale.*/
/* indice di riga (sorgente) */
int si;
/* indice di colonna (destinazione) */
int dj;
/* output corrente della sorgente i */
double sumProdIJ;
/* input corrente della destinazione j*/
double sumReqIJ;
double delta;
double alpha;
for (int c = 0; c < nD*nS; c++) {
si = rand.Next(nS);
dj = rand.Next(nD);
sumProdIJ = 0;
for (int d = 0; d < nD; d++) sumProdIJ += u[si,d];
sumReqIJ = 0;
for (int s = 0; s < nS; s++) sumReqIJ += u[s,dj];
delta = Math.Min(prod[si]-sumProdIJ, req[dj]-sumReqIJ);
alpha = rand.NextDouble();
u[si,dj] += (alpha*delta);
}
/* aggiustamento*/
for (si = 0; si < nS; si++)
for (dj = 0; dj < nD; dj++) {
sumProdIJ = 0;
for (int d = 0; d < nD; d++) sumProdIJ += u[si,d];
sumReqIJ = 0;
for (int s = 0; s < nS; s++) sumReqIJ += u[s,dj];
delta = Math.Min(prod[si]-sumProdIJ, req[dj]-sumReqIJ);
u[si,dj] += delta;
}
}
public double[,] GetU() {
return u;
}
public int GetNS() {
return nS;
}
public int GetND() {
return nD;
}
public Soluzione Clona() {
Soluzione clone = new Soluzione(this);
clone.u = (double[,])this.u.Clone();
return clone;
}
public double Fitness () {
double costo = 0;
double cIJ = 0;
for (int si = 0; si < nS; si++)
for (int dj = 0; dj < nD; dj++) {
switch (fCosto) {
case 1:
cIJ = Math.Pow((Math.Abs(si-dj)+1),2)*u[si,dj];
break;
case 2:
cIJ =
Math.Pow((Math.Abs(si-dj)+1),2)*Math.Pow(u[si,dj], 2);
break;
case 3:
cIJ =
Math.Abs(si*dj-11)*Math.Sqrt(u[si,dj])+Math.Sqrt(u[si,dj]);
break;
case 4:
cIJ = Math.Abs(si*dj-11)*Math.Pow(u[si,dj],
2)+Math.Pow(u[si,dj], 4);
break;
default:
break;
}
costo += cIJ;
}
return costo;
}
public double Merce() {
double merce = 0;
for (int si = 0; si < nS; si++)
for (int dj = 0; dj < nD; dj++)
merce += u[si,dj];
return merce;
}
public Soluzione Muta() {
Soluzione z = this.Clona();
// scelgo a caso un elemento
int si = rand.Next(z.nS);
int dj = rand.Next(z.nD);
double[,] uZ = z.u;
// a caso lo setto al min (0) o al max
uZ[si,dj] = rand.NextDouble() >= 0.5 ? 0 :
Math.Min(prod[si],req[dj]);
// aggiusto la soluzione
for (si = 0; si < z.nS; si++)
for (dj = 0; dj < z.nD; dj++) {
double sumProdIJ = 0;
for (int d = 0; d < z.nD; d++)
sumProdIJ += uZ[si,d];
double sumReqIJ = 0;
for (int s = 0; s < z.nS; s++)
sumReqIJ += uZ[s,dj];
double delta = Math.Min(prod[si]-sumProdIJ,
req[dj]-sumReqIJ);
// alpha = 1 sottinteso
uZ[si,dj] = Math.Max(uZ[si,dj]+delta, 0);
}
return z;
}
public int[] GetProd() {
return prod;
}
public int[] GetReq() {
return req;
}
public int GetFCosto() {
return fCosto;
}
// rimpiazzare con CompareTo
public int Confronta(Soluzione x) {
return this.Fitness().CompareTo(x.Fitness());
}
public bool Uguale(Soluzione x) {
bool uguali = true;
for (int i = 0; i < nS && uguali; i++)
for (int j = 0; j < nD && uguali; j++)
uguali = u[i,j] == x.u[i,j];
return uguali;
}
public override string ToString() {
string s = "";
for (int i = 0; i < nS; i++) {
for (int j = 0; j < nD; j++) {
// s += Math.Round(u[i,j],2).ToString("0.00") + "\t";
s += "u["+i+","+j+"] ="+u[i,j] + "\n";
}
s+="\n";
}
s+="\n";
return s;
}
}
}
----------------------------------------------------------------------------------------------
This is the output
----------------------------------------------------------------------------------------------
Fitness 3=Non un numero reale (that is 'not a number' in Italian)
u[0,0] =0,645759544586035
u[0,1] =0
u[0,2] =0,0175906380334083
u[0,3] =0,349247457857778
u[0,4] =0,0210873891839998
u[0,5] =3,96631497033878
u[1,0] =0,286085618731453
u[1,1] =0,372272107842662
u[1,2] =1,2791667337149
u[1,3] =2,25893076399279
u[1,4] =0,0900398541882886
u[1,5] =0,71350492152991
u[2,0] =3,52830816941484
u[2,1] =5,272095936
u[2,2] =4,32616900310448
u[2,3] =4,57385969305198
u[2,4] =8,75662771182562E-06
u[2,5] =2,29955844180099
u[3,0] =2,10553080996468
u[3,1] =2,26539317651639
u[3,2] =0
u[3,3] =-1,77635683940025E-15 ----> it is negative! absurd!
u[3,4] =0
u[3,5] =10,6290760135189
u[4,0] =1,43431585730299
u[4,1] =0,0902387796409421
u[4,2] =2,37707362514721
u[4,3] =0,817962085097459
u[4,4] =7,888864
u[4,5] =2,39154565281139
Fitness 1=383,121099950505
u[0,0] =4,7550011217406
u[0,1] =0,241038878259402
u[0,2] =0,00395999999999999
u[0,3] =0
u[0,4] =0
u[0,5] =0
u[1,0] =3,0289
u[1,1] =0,5442669362372
u[1,2] =0,910992251562801
u[1,3] =0,366624599999999
u[1,4] =0,1492162122
u[1,5] =0
u[2,0] =0,190926198835202
u[2,1] =1,84422971053786
u[2,2] =3,5556601809682
u[2,3] =0,00214166337232413
u[2,4] =0,031324627313322
u[2,5] =14,3757176189731
u[3,0] =0
u[3,1] =5,192
u[3,2] =3,529387567469
u[3,3] =5,51189017097053
u[3,4] =0,0236308592012779
u[3,5] =0,743091402359193
u[4,0] =0,0251726794242
u[4,1] =0,178464474965537
u[4,2] =0
u[4,3] =2,11934356565715
u[4,4] =7,7958283012854
u[4,5] =4,88119097866772
-----------------------------------------------------------------------------------------------