H Aßdøµ
H Aßdøµ

Reputation: 3065

How do I set the debugger to catch what changed the variable

I am implementing the NEH algorithm following this slide and video: http://mams.rmit.edu.au/b5oatq61pmjl.pdf https://www.youtube.com/watch?v=TcBzEyCQBxw

My problem during the test is the variable Sorted_list got changed which cause different results from what I expect: This the portion where I have the problem but I couldn't know what it changes it(I used breakpoints and watch variable window):

for (int i = 0; i < kmsList.Count; i++)
    {
        for (int j = 0; j < kmsList[i].Length - 1; j++)
        {
            /*
            *
            *   HERE Sorted_list GET MODIFIED UNEXPECTEDLY
            */
            if (i == 0 && j == 0)
                kmsList[0][0] = Sorted_list[0][0];
            else if (i == 0)
                kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
            else if (j == 0)
                kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
        }
    }

Complete implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FINAL_NEH
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("entre the nmbr of jobs   : ");
            string row = Console.ReadLine();
            Console.WriteLine("entre the nmbr of machines : ");
            string column = Console.ReadLine();

            int job = int.Parse(row.ToString());
            int machine = int.Parse(column.ToString());

            List<int[]> list = new List<int[]>();
            // read the nmbrs and put it in list-----------------------------------------------------  
            for (int i = 0; i < job; i++)
            {
                list.Add(new int[machine + 1]);
                for (int j = 0; j < machine; j++)
                {
                    list[i][j] = int.Parse(Console.ReadLine());
                }

                list[i][list[i].Length - 1] = int.Parse((i + 1).ToString()); //Last Elemnt Is Job Number-
            }

            // show the list----------------------------------------------------------------------------
            for (int i = 0; i < job; i++)
            {
                for (int j = 0; j < machine + 1; j++)
                {
                    Console.Write("\t" + "[" + list[i][j] + "]");
                }

                Console.WriteLine();
            }

            // sort the list------------------------------------------------------------------------------
            for (int i = 0; i < list.Count; i++)
            {
                for (int j = i + 1; j < list.Count; j++)
                {
                    int sumI = 0, sumJ = 0;

                    for (int a = 0; a < list[i].Length - 1; a++)
                    {
                        sumI += list[i][a];
                    }

                    for (int a = 0; a < list[j].Length - 1; a++)
                    {
                        sumJ += list[j][a];
                    }

                    if (sumI < sumJ)
                    {
                        int[] temp = new int[int.Parse(job.ToString())];
                        temp = list[i];
                        list[i] = list[j];
                        list[j] = temp;
                    }
                }


            }

            Console.Write("\n\n-----------------after sorting ------------------------------------\n\n");

            // shaw the list after sorting------------------------------------------
            for (int i = 0; i < job; i++)
            {
                for (int j = 0; j < machine + 1; j++)
                {
                    Console.Write("\t" + "[" + list[i][j] + "]");
                }

                Console.WriteLine();
            }



            // clculate the maxpane of the first 2 jobs---------------------------------------
            List<int[]> initMaxpane = new List<int[]>();
            initMaxpane.Add((int[])list[0].Clone());
            initMaxpane.Add((int[])list[1].Clone());

            // calculer maxspan of  first jobs..............................................
            for (int i = 0; i < initMaxpane.Count; i++)
            {
                for (int j = 0; j < initMaxpane[i].Length - 1; j++)
                {
                    if (j == 0 && i == 0)
                        initMaxpane[0][0] = list[i][j];
                    else if (i == 0)
                        initMaxpane[0][j] = (int)(initMaxpane[0][j - 1] + list[0][j]);
                    else if (j == 0)
                        initMaxpane[i][0] = (int)(initMaxpane[i - 1][0] + list[i][0]);
                }
            }

            for (int i = 1; i < initMaxpane.Count; i++)
            {
                for (int j = 1; j < initMaxpane[i].Length - 1; j++)
                {
                    if ((initMaxpane[i][j - 1] > initMaxpane[i - 1][j]))
                        initMaxpane[i][j] = (int)(initMaxpane[i][j - 1] + list[i][j]);
                    else
                        initMaxpane[i][j] = (int)(initMaxpane[i - 1][j] + list[i][j]);
                }
            }

            int Cmax = initMaxpane[initMaxpane.Count - 1][initMaxpane[initMaxpane.Count - 1].Length - 2];



            Console.WriteLine("\n\n-------the maxpane offirst jobs----------");
            for (int i = 0; i < initMaxpane.Count; i++)
            {
                for (int j = 0; j < initMaxpane[i].Length; j++)
                {
                    Console.Write("\t" + "[" + initMaxpane[i][j] + "]");
                }

                Console.WriteLine();
            }


            List<int[]> initMaxpane2 = new List<int[]>();
            initMaxpane2.Add(list.ElementAt(1));
            initMaxpane2.Add(list.ElementAt(0));

            // calculer maxspan of  first jobs reverse..............................................
            for (int i = 0; i < initMaxpane2.Count; i++)
            {
                for (int j = 0; j < initMaxpane2[i].Length - 1; j++)
                {
                    if (j == 0 && i == 0)
                        initMaxpane2[0][0] = list[i][j];
                    else if (i == 0)
                        initMaxpane2[0][j] = (int)(initMaxpane2[0][j - 1] + list[0][j]);
                    else if (j == 0)
                        initMaxpane2[i][0] = (int)(initMaxpane2[i - 1][0] + list[i][0]);
                }
            }

            for (int i = 1; i < initMaxpane2.Count; i++)
            {
                for (int j = 1; j < initMaxpane2[i].Length - 1; j++)
                {
                    if ((initMaxpane2[i][j - 1] > initMaxpane2[i - 1][j]))
                        initMaxpane2[i][j] = (int)(initMaxpane2[i][j - 1] + list[i][j]);
                    else
                        initMaxpane2[i][j] = (int)(initMaxpane2[i - 1][j] + list[i][j]);
                }
            }

            int Cmax2 = initMaxpane2[initMaxpane2.Count - 1][initMaxpane2[initMaxpane2.Count - 1].Length - 2];
            Console.WriteLine("\n\n-------the maxpane of first jobs (reverse)----------");
            for (int i = 0; i < initMaxpane2.Count; i++)
            {
                for (int j = 0; j < initMaxpane2[i].Length; j++)
                {
                    Console.Write("\t" + "[" + initMaxpane2[i][j] + "]");
                }

                Console.WriteLine();
            }

            List<int[]> MaxpaneList = new List<int[]>();
            if (Cmax > Cmax2)
            {
                MaxpaneList.Add((int[])list[1].Clone());
                MaxpaneList.Add((int[])list[0].Clone());
            }
            else
            {
                MaxpaneList.Add((int[])list[0].Clone());
                MaxpaneList.Add((int[])list[1].Clone());
            }

            List<int[]> bestSequenceList = null;
            List<int[]> kmsList = null;
            List<int[]> Sorted_list = list.ToList();
            int bestCma = 0;
            //int maxspan = 0;

            for (int jo = 2; jo < job; jo++)
            {
                for (int ins = 0; ins <= MaxpaneList.Count; ins++)
                {
                    MaxpaneList.Insert(ins, list[jo]);
                    kmsList = MaxpaneList.ToList();
                    int Cma = 0;
                    for (int i = 0; i < kmsList.Count; i++)
                    {
                        for (int j = 0; j < kmsList[i].Length - 1; j++)
                        {
                            /*
                            *
                            *   HERE Sorted_list GET MODIFIED UNEXPECTEDLY
                            */
                            if (i == 0 && j == 0)
                                kmsList[0][0] = Sorted_list[0][0];
                            else if (i == 0)
                                kmsList[0][j] = kmsList[0][j - 1] + Sorted_list[0][j];
                            else if (j == 0)
                                kmsList[i][0] = kmsList[i - 1][0] + Sorted_list[i][0];
                        }
                    }

                    for (int i = 1; i < kmsList.Count; i++)
                    {
                        for (int j = 1; j < kmsList[i].Length - 1; j++)
                        {
                            if ((kmsList[i][j - 1] > kmsList[i - 1][j]))
                                kmsList[i][j] = kmsList[i][j - 1] + Sorted_list[i][j];
                            else
                                kmsList[i][j] = kmsList[i - 1][j] + Sorted_list[i][j];
                        }
                    }

                    Cma = kmsList[kmsList.Count - 1][kmsList[kmsList.Count - 1].Length - 2];
                    Console.WriteLine("\n\n\n------- the maxpane sequence ----------");
                    for (int i = 0; i < MaxpaneList.Count; i++)
                    {
                        for (int j = 0; j < MaxpaneList[i].Length; j++)
                        {
                            Console.Write("\t" + "[" + MaxpaneList[i][j] + "]");
                        }

                        Console.WriteLine();
                    }

                    Console.WriteLine("MAX   : " + Cma + "\n\n\n");
                    if (ins == 0)
                    {
                        bestCma = Cma;
                    }

                    if (jo == 2 && ins == 0)
                    {
                        bestSequenceList = MaxpaneList.ToList();
                        bestCma = Cma;
                    }
                    else
                    {
                        if (bestCma > Cma)
                        {
                            bestSequenceList = MaxpaneList.ToList();
                            bestCma = Cma;
                        }
                    }

                    MaxpaneList.RemoveAt(ins);
                }

                MaxpaneList = bestSequenceList.ToList();
            }

            Console.ReadLine();
        }
    }
}

Upvotes: 2

Views: 109

Answers (2)

Odrai
Odrai

Reputation: 2353

The issue lies in the following code (snippet):

List<int[]> Sorted_list = list.ToList();

ToList will create a new list, but because in this case int[] is a reference type then the new list will contain references to the same arrays as the original list.

Updating a value (of an array) referenced in the new list will also affect the equivalent value in the original list.

kmsList[0][0] = Sorted_list[0][0];

The solution is to create a real copy of 'list' and its items (in this case int[]):

List<int[]> Sorted_list  = list.ConvertAll(myArray => (int[])myArray.Clone());

This piece of code clones all arrays within the list to a new variable Sorted_list.

A useful link that explains the difference between value and reference types is: https://msdn.microsoft.com/en-us/library/t63sy5hs.aspx

Reference Types

A reference type contains a pointer to another memory location that holds the data.

Reference types include the following:

  • String
  • All arrays, even if their elements are value types Class
  • types, such as Form
  • Delegates

Upvotes: 3

Ray Fischer
Ray Fischer

Reputation: 996

When you create a List<> (or any other container) from another container (as you do when you call list.ToList()) you do not create copies of all of the elements in the container. You create new references to the items in the list that you're copying. In CS parlance it's a shallow copy and not a deep copy.

So, if you do this:

        int[] ia = new[] {0, 1, 2, 3, 4};
        int[] ib = new[] {5, 6, 7, 8, 9};
        List<int[]> la = new List<int[]>() { ia, ib };
        List<int[]> lb = la.ToList();

Both lists refer to the same two arrays, and if you change one array like this:

        la[1][4] = 10;

Then lb[1][4] will also be 10 because the two lists each contain the same arrays. Copying the list does not copy the elements in the list.

Upvotes: 3

Related Questions