SauronZ
SauronZ

Reputation: 355

PHP: Add events to working days of a week

I need help in the way for doing this, not the code (tha's my work i think ;) )

I need to distribute the visits that a vendor must do during a month in the working days. I havve 100 people to visit this month, with different periodical parameters.

25 people to visit once a month. 25 people to visit twice a month 25 people to visit once a week 25 people to visit every day

I need to distribute all those visits every first day of the month, throught all the working days of the month and i really don't have any idea of how can i doit.

I get some of the data i think i need with the next code :

$days_this_month = date("d",mktime(0,0,0,$month+1,0,$year));


function weeks_this_month($year, $month, $start = 0) {
$unix = strtotime ( "$year-$month-01" );
$numDays = date ( 't', $unix );
if ($start === 0) {
    $dayOne = date ( 'w', $unix ); // Based on 0-6
} else {
    $dayOne = date ( 'N', $unix ); //based on 1-7
    $dayOne --; //convert for 0 based weeks
}

//if day one is not the start of the week then advance to start
$numWeeks = floor ( ($numDays - (6 - $dayOne)) / 7 );
return $numWeeks;
}
$weeks_this_month = weeks_this_month($year, $month);

I also get the days per week with:

$weekArray = array();

// set current date1
$date = date("m/d/Y"); //'05/09/2011';
$date = "05/11/2011"; //'05/09/2011';

// parse about any English textual datetime description into a Unix timestamp
$ts = strtotime( $date );

// calculate the number of days since Monday
$dow = date('w', $ts);
$offset = $dow - 1;
if ($offset < 0) $offset = 6;

// calculate timestamp for the Monday
$ts = $ts - $offset*86400;

// loop from Monday till Sunday
for ($i=0; $i<7; $i++, $ts+=86400){
    $temp_date = date("Y-m-d", $ts);  // here I set it to the same format as my database
    array_push( $weekArray, $temp_date );
}

print_r ($weekArray);

With the current result:

[0] => 2011-05-09
[1] => 2011-05-10
[2] => 2011-05-11
[3] => 2011-05-12
[4] => 2011-05-13
[5] => 2011-05-14
[6] => 2011-05-15

And my last check is a function to know if the resultants days are working days, not Sat or Sun.

The problem is that i am really lost.

I don't know the way to mix all this info to distribute the vendor visits.

Anyone could give me an idea please?

Really thnx.

Upvotes: 2

Views: 782

Answers (1)

AJ.
AJ.

Reputation: 3102

This is only a partial answer, but if I rephrase the question:

  • How can I distribute X visits over Y days, where each X falls requires a specific periodicity (time cycle), lets call it p? The periodicities are: daily, weekly, twice a month, and monthly. The "available days" are work days falling in a given month period.

So some of the things which you need to know as inputs to the problem:

  • Which month is the data being calculated for? (months have different lengths)
  • Which days in the month are "work" days?
  • How long does a "visit" X take (or more significantly, how many X's can take place in a given day)?

Assuming you know which month you are calculating, your logic above provides a way to get the dates in a specific month. The working days are also calculated. You need to know (or get) the number of visits which can fit into a single day; without this constraint you will not be able to "schedule" the visits. Here's the logic I would follow (loosely):

Get Available Days

  1. Get the month to calculate
  2. Get the rules for identifying "work" days
  3. Use the month to get all available days, then the rules in #2 to identify the work days
  4. Create a new list which only contains the work days

So far so good - we've got a discrete list of "available days"; now we look at a possible labor distribution algorithm.

Get needed visits

  1. Get the number of each visits by periodicity class (e.g. 25 daily, 25 weekly, 25 bi-monthly, 25 monthly)
  2. Get the maximum number of "visits" allowed per day (slots)
  3. Working from the highest frequency to lowest, begin distribution of the visits
  4. If a day is full, check the next day or raise an error (throw an exception)

Hopefully #5 and #6 will be obvious, but I'll explain #7 a bit... If you want to allocate visits, and assuming all visits are of equal priority, then one approach would be to start with the highest frequency and then work backwards to the lowest. If you have daily visits, then spread them out first, then the weekly, then the bi-weekly, then the monthly. Each periodicity has a different set of constraints, so it probably makes sense to isolate the logic. The rough idea is:

Daily

  • Work through each available day, add one visit of type daily for each X
  • If a day runs out of spaces (slots) then raise an error

Weekly

  • Identify the weeks membership for each available day
  • For each week
    • Check the first day to see it has any space
    • If so, add as many visits of X as will fit
    • If visits X > spaces then move to next day and continue to try to allocate members of X
    • If you run out of days and still have X's remaining then raise an error

Bi Monthly

  • Get the list of available days
  • Check the first day to see it has any space
  • If so, add as many visits of X as will fit
  • If visits X > spaces then move to next day and continue to try to allocate members of X
  • If you run out of days and still have X's remaining then raise an error
  • Repeat the process, but now you need to ensure the second visit falls with the same month on a day other than the original

Monthly

  • Effectively the same as the weekly, only you only need to allocate a single visit for the entire month.

...

There are some problems still left to be solved, depending on your purposes...

  • Identify how many visits can be made in a day (slots)
  • Identify if all visits are of equal value, or if some are more important than others. If they are different, then you should change the algorithm to first allocate high priority visits, then lower.
  • There is no accommodation given for travel time of visits (a la traveling salesman problem)
  • There is an implicit assumption that there is only a single person who can do the visits... if you have multiple people doing the visiting then you need to apportion their time to come up with an idea of how many slots are available in a given day
  • In the same way that all the visits are currently being treated as equal, there is no consideration given to the nature of the visitor or the visitee (person/business being visited).. If there are visitor-visitee specific relationships to be taken into account then you will need to add this

Just a few thoughts. Hope this helps.

Upvotes: 1

Related Questions