Could somebody help me?

This function should call to make_schedule(temp_lim) until the returned value "gap" satisfies me.

I know for sure (same function in c++), that "gap < 1" takes up to 10k-15k runs, ... ,"gap < 5" takes ~fifty runs. But here in C# it goes to "not responding" immediately (endless loop?) !!

public void make_weighted_schedule(Limitation lim)
		{
            Limitation temp_lim = new Limitation(lim);
            int attempts = 1;
            double gap = double.NaN;
            while (true)
            {
                gap = make_schedule(temp_lim);
                if (gap < 1)
                {
                    MessageBox.Show(gap.ToString());
                    break;
                }
                else
                {
                    temp_lim = lim;
                    attempts++;
                }
            }
            output_string = output_string + temp_lim.print_limitations();
            output_string = output_string + print_schedule();
            output_string = output_string + Environment.NewLine + "The maximum gap is " + gap + " weighted shift! It took " + attempts + " attempts." + Environment.NewLine;
		}

Though, if i change line 6 to: while (attempts < 1000000)
the whole thing runs 1000000 times.

It never reaches line 11 at all!!

i thing the problem is, that in C# the program doesn't wait for make_schedule(temp_lim) to complete, and goes on with the old value of "gap" to endless loop.

Recommended Answers

All 5 Replies

It waits just like in any language where you make a call to a method, that method has to finish first before the next line of code can be executed.

Something I noticed, which I dont know if it is the problem or not, in your else statement you alwasy set temp_lim to lim, so you are always passing the same value to make_scedule because you never change the value of lim anywhere.

The reason it never reaches line 11, is because the condition is never true. You are always passing the same value to make_schedule.

Because gap is always greater than 1 so the if text never get executed.
;)

It waits just like in any language where you make a call to a method, that method has to finish first before the next line of code can be executed.

Something I noticed, which I dont know if it is the problem or not, in your else statement you alwasy set temp_lim to lim, so you are always passing the same value to make_scedule because you never change the value of lim anywhere.

The reason it never reaches line 11, is because the condition is never true. You are always passing the same value to make_schedule.

oh, I forgot no mention. The make_scedule() uses random numbers and also changes its argument. That's the reason i always set temp_lim back to lim.

When i let it run with (attempts < anynumber) i get different results each time, because of the random number.

Because gap is always greater than 1 so the if text never get executed.
;)

Same shit with "if (gap < 5)", it goes to "not responding".

In c++ gap < 5 is very common.

Here is whole code, if you wish:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MainForm
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        public void button1_Click_1(object sender, EventArgs e)
        {
            Limitation mylim = new Limitation();
            Schedule mysched = new Schedule();

            textBox1.Text = "";

            mysched.make_weighted_schedule(mylim);

            textBox1.Text = textBox1.Text + mysched.output_string;

        }
        public static Random RandomClass = new Random();
        public const int const_number_workers = 7;
        public const int const_max_shifts_per_day = 3;
        public const int const_days_per_week = 7;
        public const int const_number_shifts = const_max_shifts_per_day * const_days_per_week;
        public const int const_max_workers_on_shift = 3;
        public const bool night_worker_should_be_ready = true;
        public const bool night_shifts_exist = true;
        public static int[] workers_on_shift = new int[const_number_shifts] {2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 3, 1, 3, 1, 1, 1, 1, 1};
        public static double[] shift_values = new double[const_number_shifts] {1.0, 1.0, 1.5, 1.0, 1.0, 1.5, 1.0, 1.0, 1.5, 1.0, 1.0, 1.5, 1.0, 1.0, 1.5, 1.0, 1.25, 2.0, 2.0, 1.75, 1.5};

        //for given shift, returns the avaliable workers
        public static List<int> avaliabilty_by_shift(ref Limitation lim, int shift_ID)
        {
            List<int> avaliable_workers = new List<int>();
            for (int i = 0; i < const_number_workers; i++)
            {
                if (lim.workers_shifts_array[i, shift_ID] == 1)
                    avaliable_workers.Add(i);
            }
            return avaliable_workers;
        }

        //for given worker, returns his avaliable shifts
        public static List<int> avaliabilty_by_worker(ref Limitation lim, int worker_ID)
        {
            List<int> avaliable_shifts = new List<int>();
            for (int j = 0; j < const_number_shifts; j++)
            {
                if (lim.workers_shifts_array[worker_ID, j] == 1)
                    avaliable_shifts.Add(j);
            }
            return avaliable_shifts;
        }

        //random worker generator out of avaliable workers
        public static int give_random_worker(List<int> workers)
        {  
	        return workers[RandomClass.Next(workers.Count())];
        }
    }

    public class Limitation
    {
        public int[,] workers_shifts_array = new int[MainForm.const_number_workers, MainForm.const_number_shifts];

        public Limitation()
		{
            for (int i = 0; i < MainForm.const_number_workers; i++)
			{
                for (int j = 0; j < MainForm.const_number_shifts; j++)
					workers_shifts_array[i, j] = 1;
			}
		}

        public Limitation(Limitation L)
        {
            for (int i = 0; i < MainForm.const_number_workers; i++)
            {
                for (int j = 0; j < MainForm.const_number_shifts; j++)
                    workers_shifts_array[i, j] = L.workers_shifts_array[i, j];
            }
        }

        public string print_limitations()
		{
            string output_string = "";
			output_string = output_string + "shabat" + "		" + "shishi" + "		" + "hamishi" + "		";
            output_string = output_string + "revii" + "		" + "shlishi" + "		" + "sheni" + "		" + "rishon" + Environment.NewLine;
            for (int i = 0; i < MainForm.const_days_per_week; i++)
			{
                for (int j = MainForm.const_number_workers - 1; j >= 0; j--)
                    output_string = output_string + (j + 1) + " ";
                output_string = output_string + "	";
			}
            output_string = output_string + Environment.NewLine + Environment.NewLine;
            for (int x = MainForm.const_max_shifts_per_day; x > 0; x--)
			{
                for (int i = MainForm.const_number_shifts - x; i >= 0; i = i - MainForm.const_max_shifts_per_day)
				{
                    for (int j = MainForm.const_number_workers - 1; j >= 0; j--)
                        output_string = output_string + workers_shifts_array[j, i] + " ";
                    output_string = output_string + "	";
				}
                output_string = output_string + Environment.NewLine + Environment.NewLine;
			}
            output_string = output_string + Environment.NewLine;
            return output_string;
		}
    };

    class Schedule
    {
        public int[,] shifts_workers_array = new int[MainForm.const_number_shifts, MainForm.const_max_workers_on_shift];
        public bool[,] preset_shifts_array = new bool[MainForm.const_number_shifts, MainForm.const_max_workers_on_shift];  
        public double[] scheduled_shifts_for_workers = new double[MainForm.const_number_workers];
        public double[] scheduled_wheighted_shifts_for_workers = new double[MainForm.const_number_workers];
        public string output_string = "";

		public Schedule()
		{
            for (int i = 0; i < MainForm.const_number_shifts; i++)
			{
                for (int j = 0; j < MainForm.const_max_workers_on_shift; j++)
				{
					shifts_workers_array[i, j] = -1;
					preset_shifts_array[i, j] = false;
				}
			}
            for (int k = 0; k < MainForm.const_number_workers; k++)
			{
				scheduled_shifts_for_workers[k] = -1;
                scheduled_wheighted_shifts_for_workers[k] = -1;
			}
		}

        public string print_schedule()
		{
            string output_string = "";
            output_string = output_string + "shabat" + "		" + "shishi" + "		" + "hamishi" + "		";
            output_string = output_string + "revii" + "		" + "shlishi" + "		" + "sheni" + "		" + "rishon" + Environment.NewLine + Environment.NewLine;
            for (int x = MainForm.const_max_shifts_per_day; x > 0; x--)
			{
                for (int i = MainForm.const_number_shifts - x; i >= 0; i = i - MainForm.const_max_shifts_per_day)
				{
                    for (int j = 0; j < MainForm.workers_on_shift[i]; j++)
                        output_string = output_string + (shifts_workers_array[i, j] + 1) + " ";
                    output_string = output_string + "		";
				}
                output_string = output_string + Environment.NewLine + Environment.NewLine;
			}
            for (int i = 0; i < MainForm.const_number_workers; i++)
			{
                output_string = output_string + "Worker # " + (i + 1) + " got " + scheduled_shifts_for_workers[i];
                output_string = output_string + " shifts, which are " + scheduled_wheighted_shifts_for_workers[i] + "  weighted shifts" + Environment.NewLine;
			}
            return output_string;
		}

		//calculates the number of shifts and weighted shifts of all workers
        public void calculate_given_shifts()
		{
            for (int worker_ID = 0; worker_ID < MainForm.const_number_workers; worker_ID++)
			{
				double n = 0, m = 0;
                for (int i = 0; i < MainForm.const_number_shifts; i++)
				{
                    for (int j = 0; j < MainForm.workers_on_shift[i]; j++)
					{
						if (shifts_workers_array[i, j] == worker_ID)
						{
							m++;
                            n = n + MainForm.shift_values[i];
						}
					}
				}
				scheduled_shifts_for_workers[worker_ID] = m;
                scheduled_wheighted_shifts_for_workers[worker_ID] = n;
			}
		}

		//set the given worker for given shift, return status
        public bool set_worker_on_shift(ref Limitation l, int worker_ID, int shift_ID)
		{
            if ((shift_ID < 0) || (shift_ID >= MainForm.const_number_shifts) || (worker_ID < 0) || (worker_ID >= MainForm.const_number_workers))
				return false;

			l.workers_shifts_array[worker_ID, shift_ID] = 0; // worker can not replicate himself

            for (int k = 1; (k < MainForm.const_max_shifts_per_day) && (shift_ID + k < MainForm.const_number_shifts); k++) // next shifts limited
			{
                if ((shift_ID + 1) % MainForm.const_max_shifts_per_day == 0) // if night shift 
				{
                    if (MainForm.night_shifts_exist == true) // if night shift
					{
                        if (k <= (MainForm.const_max_shifts_per_day / (Convert.ToInt32(MainForm.night_worker_should_be_ready) + 1)))
							l.workers_shifts_array[worker_ID, shift_ID+k] = 0;
					}
				}
				else
				{
					l.workers_shifts_array[worker_ID, shift_ID+k] = 0;
                    if ((shift_ID + k + 1) % MainForm.const_max_shifts_per_day == 0) // allow day workers to work on next day morning
						break;
				}
			}

            for (int k = 1; (k < MainForm.const_max_shifts_per_day) && (shift_ID - k >= 0); k++) // previous shifts limited
			{
                if ((shift_ID + 1) % MainForm.const_max_shifts_per_day == 0) // if last shift
						l.workers_shifts_array[worker_ID, shift_ID-k] = 0;
				else
				{
                    if ((shift_ID - k + 1) % MainForm.const_max_shifts_per_day != 0)
						l.workers_shifts_array[worker_ID, shift_ID-k] = 0;
					else
					{
                        if (MainForm.night_shifts_exist == true)
						{
                            if ((MainForm.night_worker_should_be_ready == false) || ((shift_ID % MainForm.const_max_shifts_per_day) < (int)(MainForm.const_max_shifts_per_day / 2)))
								l.workers_shifts_array[worker_ID, shift_ID-k] = 0;
							break;
						}
					}
				}
			}

            for (int i = 0; i < MainForm.workers_on_shift[shift_ID]; i++)
			{	
				if (shifts_workers_array[shift_ID, i] == -1)
				{
					shifts_workers_array[shift_ID, i] = worker_ID;
					preset_shifts_array[shift_ID, i] = true;
					scheduled_shifts_for_workers[worker_ID]++;
                    scheduled_wheighted_shifts_for_workers[worker_ID] = scheduled_wheighted_shifts_for_workers[worker_ID] + MainForm.shift_values[shift_ID];
					return true;
				}
			}
			return false;
		}

        public double make_schedule(Limitation temp_lim)
		{
			List<int> avaliable_workers;
			int worker_ID;
            for (int i = 0; i < MainForm.const_number_shifts; i++)
			{
                for (int j = 0; j < MainForm.workers_on_shift[i]; j++)
				{
					if (preset_shifts_array[i, j] == false) // if not pre-set by the boss
					{
                        avaliable_workers = MainForm.avaliabilty_by_shift(ref temp_lim, i);
                        worker_ID = MainForm.give_random_worker(avaliable_workers);
						shifts_workers_array[i, j] = worker_ID;
						preset_shifts_array[i, j] = true;
						temp_lim.workers_shifts_array[worker_ID, i] = 0; // worker cannot replicate himself
                        for (int k = 1; (k < MainForm.const_max_shifts_per_day) && (i + k < MainForm.const_number_shifts); k++)
						{
                            if ((i + 1) % MainForm.const_max_shifts_per_day == 0) // if last shift
							{
                                if (MainForm.night_shifts_exist == true) // if night shift
								{
                                    if (k <= (MainForm.const_max_shifts_per_day / (Convert.ToInt32(MainForm.night_worker_should_be_ready) + 1)))
										temp_lim.workers_shifts_array[worker_ID, i+k] = 0;
								}
							}
							else
							{
								temp_lim.workers_shifts_array[worker_ID, i+k] = 0;
                                if ((i + k + 1) % MainForm.const_max_shifts_per_day == 0) // allow day workers to work on next day morning
									break;
							}
						}
					}
				}
			}
			calculate_given_shifts();
            double min_worker = scheduled_wheighted_shifts_for_workers.Min();
            double max_worker = scheduled_wheighted_shifts_for_workers.Max();
            return (max_worker - min_worker);
		}
 
        public void make_weighted_schedule(Limitation lim)
		{
            Limitation temp_lim = new Limitation(lim);
            int attempts = 1;
            double gap = double.NaN;
            while (true)
            // while (attempts < 100000)
            {
                gap = make_schedule(temp_lim);
                if (gap < 1)
                {
                    MessageBox.Show(gap.ToString());
                    break;
                }
                else
                {
                    temp_lim = lim;
                    attempts++;
                }
            }
            output_string = output_string + temp_lim.print_limitations();
            output_string = output_string + print_schedule();
            output_string = output_string + Environment.NewLine + "The maximum gap is " + gap + " weighted shift! It took " + attempts + " attempts." + Environment.NewLine;
		}
    };
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.