#!/usr/local/bin/perl -W

@product= qw( A      B     C     D);
@demand = qw(123456 23456 34567 10000);            # anual
@costp  = qw(  4    6     7     6   );
@profit = qw(1.2    2.3   3.1   2.3 );
@capacity=qw(150000 40000 50000 30000);
$N = scalar(@capacity);
@holding= qw(0.1    0.1   0.1   0.1);              # costs, %
@setup=   qw(500    400   450   100);              # cost per setup, absolute

$daysyear = 365 - 52*2;
for $i (0..$N-1){
    $rated[$i] = $demand[$i]/$daysyear; 
    $ratep[$i] = $capacity[$i]/$daysyear;
    die "Production < demand in product $product[$i]" if $ratep[$i]<$rated[$i];
    $h[$i] = $holding[$i]*$costp[$i]/$daysyear;
}

$mincost = 9e99;
while (1){
    $day=0;
    $P = 1+ int (rand() * 2*$daysyear/$N); # period of plannig, max. days
    for $i (0..$N-1){
	$period[$i] = int (rand()*$P);
    }
    $j = 0;
    $chold = $csetup = $coport = 0;
    @stock = ();
    while ($day<=$daysyear){
	$day+=$period[$j];
	$csetup += $setup[$j];
	$chold += ($ratep[$j]-$rated[$j])*$h[$j]*$period[$j]/2; 
	for $i (0..$N-1){
	    if ($i == $j){
		$stock[$i] += int(($ratep[$i]-$rated[$i])*$period[$i]);
	    }else{
		$stock[$i] -= int($rated[$i] * $period[$j]);
		if ($stock[$i] < 0 ) { 
		    $coport += abs($stock[$i]*$profit[$i]); # oportunity cost 
		    $stock[$i] =0; 
		}
	    }
	}
	$cost = $csetup + $chold + $coport;
	last if ($cost > $mincost);
	$j++;
	if ($j>=$N) { $j=0; }
    }
    if ($cost < $mincost){
	$mincost=$cost; 
	print "Cost = $cost\n times @period\n stock @stock\n";
	print "chold = $chold csetup = $csetup coport = $coport\n";
    }
}



__END__
  
PCP stands for Product Cycling Problem

v.0.1 - initial experiment with 3 products  
v.0.2 - labour year, 5 days per week
v.0.3 - fixed a bug in the holding cost
v.0.4 - added a 4th product, with small setup cost  
v.0.5 - fixed a bug in $P, and renaming

Time for understanding the results:
  ...
  Cost = 165470.636226714229
   times 107 0 21 3
   stock 0 0 844 229
  Cost = 165282.288216555834
   times 107 1 22 1
   stock 0 0 1168 76
  
v.0.6 - splitting the costs  
  ...
  Cost = 166394.158352050029
   times 72 1 14 1
   stock 227 0 827 0
  chold = 20.5583520500286255 csetup = 4250 coport = 162123.6
  Cost = 165016.286239192026
   times 106 0 25 0
   stock 0 0 1478 0
  chold = 20.4862391920259538 csetup = 2800 coport = 162195.8
  
