if ($days_running >= 8) { echo $strPriorityBasedLastWeek; } if ($days_running >= 2 && $days_running < 8) { echo $strPriorityBasedLastDays; } if ($days_running == 1) { echo $strPriorityBasedYesterday; } } else { echo $strPriorityNoData; } $banners = phpAds_PriorityPrepareBanners(); $campaigns = phpAds_PriorityPrepareCampaigns(); $profile = array(); list($profile, $profile_correction_executed) = phpAds_PriorityPredictProfile($campaigns, $banners); $estimated_hits = 0; for ($p = 0; $p < 24; $p++) { $estimated_hits += $profile[$p]; } if ($campaigns_target) { if ($estimated_hits > $campaigns_target) { echo $strPriorityEnoughAdViews; } else { echo $strPriorityNotEnoughAdViews; } } else { $campaigns_target = 0; } // Show recalculate button echo "<br><br>";
function phpAds_PriorityCalculate() { global $debug, $debuglog; // Prepare information $banners = phpAds_PriorityPrepareBanners(); $campaigns = phpAds_PriorityPrepareCampaigns(); $profile = array(); // Determine period $maxperiod = 24; $period = phpAds_CurrentHour; // Populate campaign statistics $total_requested = 0; $total_campaign_weight = 0; $total_targeted_hits = 0; $total_other_hits = 0; for (reset($campaigns); $c = key($campaigns); next($campaigns)) { $targeted_hits = 0; $other_hits = 0; if ($campaigns[$c]['target'] > 0) { for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { $targeted_hits += isset($banners[$b]['hits']) ? $banners[$b]['hits'] : 0; } } $total_targeted_hits += $targeted_hits > $campaigns[$c]['target'] ? $campaigns[$c]['target'] : $targeted_hits; $total_requested += $campaigns[$c]['target']; } else { $bannercount = 0; for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { $other_hits += isset($banners[$b]['hits']) ? $banners[$b]['hits'] : 0; $bannercount++; } } $total_other_hits += $other_hits; if ($bannercount > 0) { $total_campaign_weight += $campaigns[$c]['weight']; } } $campaigns[$c]['hits'] = $targeted_hits + $other_hits; } if ($total_requested) { // High pri campaigns present, run profiling list($profile, $profile_correction_executed) = phpAds_PriorityPredictProfile($campaigns, $banners); // Determine estimated number of hits $corrected_hits = 0; $estimated_hits = 0; for ($p = 0; $p < 24; $p++) { $corrected_hits += $profile_correction_executed && $p < phpAds_CurrentHour ? $profile[$p] : 0; $estimated_hits += $profile[$p]; } // Apply correction to other hits if ($profile_correction_executed) { // BEGIN REPORTING $debuglog .= "\n\n"; $debuglog .= abs($total_targeted_hits + $total_other_hits - $corrected_hits) . " hits were " . ($total_targeted_hits + $total_other_hits - $corrected_hits > 0 ? "added" : "removed") . " during peak compensation\n"; // END REPORTING $total_other_hits = $corrected_hits - $total_targeted_hits; } $total_hits = $total_targeted_hits + $total_other_hits; $estimated_remaining = $estimated_hits - $total_hits; $requested_remaining = $total_requested - $total_targeted_hits; if ($estimated_remaining > $requested_remaining) { $available_for_targeting = $requested_remaining; $available_for_others = $estimated_remaining - $requested_remaining; } else { $available_for_targeting = $estimated_remaining; $available_for_others = 0; } // BEGIN REPORTING $debuglog .= "\n\n"; $debuglog .= "Estimated number of impressions today: {$estimated_hits} \n"; $debuglog .= "Estimated number of impressions remaining: {$estimated_remaining} \n"; $debuglog .= "-----------------------------------------------------\n"; $debuglog .= "Total number of requested impressions: {$total_requested} \n"; $debuglog .= "Number of requested impressions satisfied: {$total_targeted_hits} \n"; $debuglog .= "Number of requested impressions remaining: {$requested_remaining} \n"; $debuglog .= "-----------------------------------------------------\n\n\n"; $debuglog .= "Impressions available to meet the targets: {$available_for_targeting} \n"; $debuglog .= "Impressions left over: {$available_for_others} \n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING $totalassigned = 0; for (reset($campaigns); $c = key($campaigns); next($campaigns)) { if ($campaigns[$c]['target'] > 0) { // BEGIN REPORTING $debuglog .= "\n\n\nHIGH-PRI CAMPAIGN {$c} \n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING // Hits assigned = $remaining_for_campaign = $campaigns[$c]['target'] - $campaigns[$c]['hits']; $total_profile = 0; for ($p = 0; $p < $maxperiod; $p++) { $total_profile += isset($profile[$p]) ? $profile[$p] : 0; } $profile_uptil_now = 0; for ($p = 0; $p < $period; $p++) { $profile_uptil_now += isset($profile[$p]) ? $profile[$p] : 0; } if ($total_profile == 0) { // No profile available yet, just divide evently $expected_hits_this_period = round($campaigns[$c]['target'] / $maxperiod * ($period + 1)); } else { if ($profile[$period] == 0) { // Profile available, but no impressions expected this hour // Set the number of expected hits to 1, to make sure the campaign isn't deactivated // and the real impressions won't bring it much of target $expected_hits_this_period = 1; } else { // Profile available, use expected impressions $expected_hits_this_period = round($profile_uptil_now / $total_profile * $campaigns[$c]['target']); } } // BEGIN REPORTING $debuglog .= "Target for campaign: " . $campaigns[$c]['target'] . " \n"; $debuglog .= "Remaining for campaign: {$remaining_for_campaign} \n"; // END REPORTING if ($period > 0) { // The first time the priority calculation is running there is no // need to compensate, since there are no previous hours available $current_deviance_from_prediction = $campaigns[$c]['hits'] / $expected_hits_this_period; // > 1 = overdelivery, < 1 = underdelivery $expected_today_without_correction = $campaigns[$c]['target'] * $current_deviance_from_prediction; $expected_deviance_todays_in_hits = $expected_today_without_correction - $campaigns[$c]['target']; // BEGIN REPORTING $debuglog .= "Real impressions up till now: " . $campaigns[$c]['hits'] . " \n"; $debuglog .= "Expected impressions up till now: {$expected_hits_this_period} \n"; $debuglog .= "Deviance from prediction: " . $current_deviance_from_prediction . "x \n"; $debuglog .= "Total impressions expected without correction: {$expected_today_without_correction} \n"; $debuglog .= "Total deviance expected without correction: {$expected_deviance_todays_in_hits} \n"; // END REPORTING $aggression = 2; // The deviance needs to be fixed in the remaining hours / agression $fix_in_no_hours = round(($maxperiod - $period) / $aggression); $extra_to_assign = 0 - $expected_deviance_todays_in_hits / $fix_in_no_hours; // BEGIN REPORTING $debuglog .= "Deviance needs to fixed in: {$fix_in_no_hours} hours (aggression " . $aggression . ")\n"; $debuglog .= "Compensate linear by: {$extra_to_assign} \n"; // END REPORTING // Find out how many impressions the next hour will generate compared // to the other hours (according to predictions). $total_next_hours = 0; for ($p = $period; $p < $period + $fix_in_no_hours; $p++) { $total_next_hours = isset($profile[$p]) ? $profile[$p] : 0; } $avg_impressions_per_hour = $total_next_hours / $fix_in_no_hours; $compensation_factor = $profile[$period] / $avg_impressions_per_hour; $extra_to_assign = round($compensation_factor * $extra_to_assign); // BEGIN REPORTING $debuglog .= "Average impressions per hour: " . $avg_impressions_per_hour . "\n"; $debuglog .= "Expected impressions next hour: " . $profile[$period] . "\n"; $debuglog .= "Deviance from average: " . $compensation_factor . "\n"; $debuglog .= "Compensate realisticly by: {$extra_to_assign} \n"; // END REPORTING $remaining_for_campaign += $extra_to_assign; if ($remaining_for_campaign < 0) { $remaining_for_campaign = 0; } } // BEGIN REPORTING $debuglog .= "Priority for whole campaign: {$remaining_for_campaign} \n"; // END REPORTING $totalassigned += $remaining_for_campaign; $total_banner_weight = 0; for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { $total_banner_weight += $banners[$b]['weight']; } } for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { $banners[$b]['priority'] = round($remaining_for_campaign / $total_banner_weight * $banners[$b]['weight']); // BEGIN REPORTING $debuglog .= "- Priority of banner {$b}: " . $banners[$b]['priority'] . " \n"; // END REPORTING } } } } // BEGIN REPORTING $debuglog .= "\n\n\n"; $debuglog .= "Impressions assigned to meet the targets: {$totalassigned} \n"; // END REPORTING $no_high_pri = !$totalassigned; } else { // BEGIN REPORTING $debuglog .= "-----------------------------------------------------\n"; $debuglog .= "No targeting needed, skipping profile prediction.\n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING $no_high_pri = true; } $total_weight = phpAds_PriorityTotalWeight($campaigns, $banners); if ($no_high_pri || !$available_for_others) { // BEGIN REPORTING if ($no_high_pri) { $debuglog .= "\n\n\nNo impressions assigned to meet the targets\n"; } else { $debuglog .= "\n\n\nNo or few impressions left over, this would result\n"; $debuglog .= "in low-priority banners never shown\n"; } $debuglog .= "Total weight: {$total_weight}\n"; // END REPORTING // Use total weight as avaliable impressions for low-pri $available_for_others = $total_weight; // Boost high-pri banners by total_weight $high_pri_boost = $total_weight; } else { // No boost $high_pri_boost = 1; } // Init array for GCD calculation $banner_priorities = array(); // Flag used when a campaign gets a null priority $zero_pri = false; // BEGIN REPORTING $debuglog .= "Impressions left over: {$available_for_others} \n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING for (reset($campaigns); $c = key($campaigns);) { if ($campaigns[$c]['target'] == 0) { // BEGIN REPORTING $debuglog .= "\n\n\nLOW-PRI CAMPAIGN {$c} \n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING if ($available_for_others > 0) { $remaining_for_campaign = round($available_for_others / $total_campaign_weight * $campaigns[$c]['weight']); } else { $remaining_for_campaign = 0; } // BEGIN REPORTING $debuglog .= "Remaining for campaign: {$remaining_for_campaign} \n"; // END REPORTING $total_banner_weight = 0; for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { $total_banner_weight += $banners[$b]['weight']; } } for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { $banners[$b]['priority'] = round($remaining_for_campaign / $total_banner_weight * $banners[$b]['weight']); if (!$banners[$b]['priority']) { // BEGIN REPORTING $debuglog .= "- Banner {$b} had a null priority.\n"; // END REPORTING $zero_pri = true; break; } $banner_priorities[] = $banners[$b]['priority']; // BEGIN REPORTING $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " \n"; // END REPORTING } } } if ($zero_pri) { if (!$available_for_others) { // It should never get here, but avoid an endless loop to be safe... break; } // Restart low-pri assignment, increasing available impressions $zero_pri = false; $banner_priorities = array(); $available_for_others *= 2; $high_pri_boost *= 2; // BEGIN REPORTING $debuglog .= "\n\n\n-----------------------------------------------------\n"; $debuglog .= "Restarting...\n"; $debuglog .= "-----------------------------------------------------\n"; $debuglog .= "\n\n\nImpressions left over: {$available_for_others} \n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING reset($campaigns); continue; } next($campaigns); } if ($high_pri_boost > 1 && !$no_high_pri && $total_weight) { // We need to raise high-pri priorities to reduce the side-effect // introduced increasing remaining impressions for low-pri campaigns // BEGIN REPORTING $debuglog .= "\n\n\n-----------------------------------------------------\n"; $debuglog .= "HIGH PRIORITY CAMPAIGNS BOOST ENABLED\n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING // Try to find a GCD to avoid to reduce priority values $banner_priorities[] = $high_pri_boost; $gcd = phpAds_PriorityGetGCD($banner_priorities); if ($gcd > 1) { // A GCD was found, we can lower boost rate and low-pri priorities $high_pri_boost /= $gcd; // BEGIN REPORTING $debuglog .= "GCD PRIORITY SOFTENER ENABLED\n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING } for (reset($campaigns); $c = key($campaigns); next($campaigns)) { if ($campaigns[$c]['target'] > 0) { // BEGIN REPORTING $debuglog .= "\n\n\nHIGH-PRI CAMPAIGN {$c} \n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { // BEGIN REPORTING $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " * {$high_pri_boost} = "; // END REPORTING $banners[$b]['priority'] *= $high_pri_boost; // BEGIN REPORTING $debuglog .= $banners[$b]['priority'] . "\n"; // END REPORTING } } } elseif ($gcd > 1) { // BEGIN REPORTING $debuglog .= "\n\n\nLOW-PRI CAMPAIGN {$c} \n"; $debuglog .= "-----------------------------------------------------\n"; // END REPORTING for (reset($banners); $b = key($banners); next($banners)) { if ($banners[$b]['parent'] == $c) { // BEGIN REPORTING $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " / {$gcd} = "; // END REPORTING $banners[$b]['priority'] /= $gcd; // BEGIN REPORTING $debuglog .= $banners[$b]['priority'] . "\n"; // END REPORTING } } } } } $priority_sum = 0; for (reset($banners); $b = current($banners); next($banners)) { $priority_sum += $b['priority']; } if ($priority_sum) { $softener = 1; while ($priority_sum / $softener > 0x7ffffffe) { $softener *= 2; } if ($softener > 1) { $debuglog .= "\n\n\n-----------------------------------------------------\n"; $debuglog .= "OVERFLOW SOFTENER ENABLED\n"; $debuglog .= "-----------------------------------------------------\n\n\n\n"; for (reset($banners); $b = key($banners); next($banners)) { // BEGIN REPORTING $debuglog .= "- Assigned priority to banner {$b}: " . $banners[$b]['priority'] . " / {$softener} = "; // END REPORTING $roundto1 = $banners[$b]['priority'] > 0; $banners[$b]['priority'] = round($banners[$b]['priority'] / $softener); if ($roundto1 && !$banners[$b]['priority']) { $banners[$b]['priority'] = 1; // BEGIN REPORTING $debuglog .= '0, rounding up to '; // END REPORTING } // BEGIN REPORTING $debuglog .= $banners[$b]['priority'] . "\n"; // END REPORTING } } } // Store priority information phpAds_PriorityStore($banners, $campaigns); return $debuglog; }