模擬生成一天溫度數據,精確到秒


需求來源:

  做一套養殖過程管理的系統,有養殖環境數據采集功能,硬件不到位,需要給相關LD演示,要求數據盡量真實。這就需要模擬生成一天的溫度數據。

解決方案1:

  指定范圍隨機數溫度生成

    

     結果就是這樣了。。。太假。。。

解決方案2:

    代碼連續隨機數生成:

        $wd_arr = array();	// 溫度
//-------------溫度--------------
	// 生成連續的溫度隨機數
	$wd_start = 21.6;
	$MAX_WD = 22.6;	//最高溫度22.6
	$MIN_WD = 7.1;	// 最低溫度7.1
	$START_OFFSET_WD = 5*60*2; // 從5點開始
	$WD_diff = $MAX_WD - $MIN_WD;	// 溫度差
	$WD_change_prob = 0.1; // 溫度變化概率
	
	// 模擬一天的氣溫,2880為每半分鍾采集一次
	$wd_arr[$START_OFFSET_WD] = $MIN_WD;
	$wd_inte1 = getRandFW( (14-5)*60*2, $WD_diff ); // 第一段的區間
	$wd_inte2 = getRandFW( (21-14)*60*2, $WD_diff * 0.9 ); // 第二段的區間
	$wd_inte3 = getRandFW( (24-21 + 5)*60*2, $WD_diff * 0.1 ); // 第三段的區間

// 模擬生成數據
	for($i=1; $i<=24*60*2; $i++){
		
		// ----------- 溫度 -------------
		// 5~14點,90%概率溫度不變, 10%概率溫度增加  
		if($START_OFFSET_WD + $i < 14*60*2 && $START_OFFSET_WD + $i > 5*60*2) {
			
			$is_change = false;
			$rd = mt_rand(1,100);
			if($rd<=100 * $WD_change_prob) {
				$is_change = true;
			}

			// 升溫
			$rd = 0;
			if($is_change) {
				//每次增加的溫度是[0.007 ~ 0.28]*100 四舍五入 再 除以100后的隨機數
				//$rd = mt_rand(7,280);
				//$rd = round ($rd / 10)/100;	// 除以10然后四舍五入

				//$inte = getRandFW( (14-5)*60*2, $WD_diff );
				$rd = mt_rand($wd_inte1['start'], $wd_inte1['end']);
				$rd = round(round ($rd / 10)/100,2);
			}

			$wd_arr[$START_OFFSET_WD + $i] = $wd_arr[$START_OFFSET_WD + $i - 1] + $rd;

		} else if ( ($START_OFFSET_WD + $i > 14*60*2) && ($START_OFFSET_WD + $i < 21*60*2) ) { // 14點以后21點之前,降低溫度差的90%

			$is_change = false;
			$rd = mt_rand(1,100);
			if($rd<=100 * $WD_change_prob) {
				$is_change = true;
			}

			// 降溫
			$rd = 0;
			if($is_change) {
				//$inte = getRandFW( (21-14)*60*2, $WD_diff * 0.9 );
				$rd = mt_rand($wd_inte2['start'], $wd_inte2['end']);
				$rd = round(round ($rd / 10)/100,2);
			}

			$wd_arr[$START_OFFSET_WD + $i] = $wd_arr[$START_OFFSET_WD + $i - 1] - $rd;

		} else {  // 21點之后,5點之前,降低溫度差的10%
			
			$is_change = false;
			$rd = mt_rand(1,100);
			if($rd<=100 * $WD_change_prob) {
				$is_change = true;
			}

			$index = $START_OFFSET_WD + $i;
			$index > 24*60*2 ? $index-=(24*60*2+1) : $index=$index;

			// 降溫
			$rd = 0;
			if($is_change) {
				//$inte = getRandFW( (24-21 + 5)*60*2, $WD_diff * 0.1 );
				$rd = mt_rand($wd_inte3['start'], $wd_inte3['end']);
				$rd = round(round ($rd / 10)/100,2);
			}

			// 大於2880
			$index = $START_OFFSET_WD + $i;
			$index > 24*60*2 ? $index-=(24*60*2+1) : $index=$index;
			//echo $index." --- ";
			$index != 0 ? $wd_arr[$index] = $wd_arr[$index-1] - $rd : $wd_arr[$index] = $wd_arr[24*60*2] - $rd;
			//echo $wd_arr[$index]."<br />";
			//$wd_arr[$index] = $wd_arr[$index-1] + $rd;

		}


date_default_timezone_set('PRC'); 
	for($i=0; $i<24*60*2; $i++ ) {

		$nowDatestep = strtotime(date("Y-m-d",time()));
		$nowtimestep = ( (intval($i/(2*60)))*3600 + (($i-($i%2==0?0:1))/2 - (intval($i/(2*60)))*60)*60 + ($i%2==0 ? 0:30) );
		$newdatetimestep = $nowDatestep + $nowtimestep;
		$nowformatTime = (intval($i/(2*60))).':'.(($i-($i%2==0?0:1))/2 - (intval($i/(2*60)))*60).':'.($i%2==0?'00':'30');


		// echo $newdatetimestep .'  '. $nowformatTime. ' ' . $wd_arr[$i]. ' ' . $sd_arr[$i]. ' ' . $gz_arr[$i]. ' ' . $aq_arr[$i]. ' ' . $yhqt_arr[$i].'<br>';

		echo $newdatetimestep .'  '. $nowformatTime. ' ' . $wd_arr[$i].  '<br>';

		//echo " ".( (intval($i/(2*60)))*3600 + (($i-($i%2==0?0:1))/2 - (intval($i/(2*60)))*60)*60 + ($i%2==0 ? 0:30) )."    ".(intval($i/(2*60))).':'.(($i-($i%2==0?0:1))/2 - (intval($i/(2*60)))*60).':'.($i%2==0?'00':'30')."    ".$wd_arr[$i].'<br>';
		//echo $i.'---'.$wd_arr[$i].'<br>';
	}

/*
	 * 根據溫度差和時間范圍確定變化率和范圍
	 * @ 時間差
	 * @ 溫度差
	 *
	 */
	function getRandFW($Time_diff, $WD_diff){
		
		// 10%的時間里溫度在降
		$bl = round( ($WD_diff / ( $Time_diff * 0.1 ) ) * 2 * 1000 );

		// 獲得個位數然后
		$inte['start'] = ($bl % 10);

		// 獲得除了個位后的數
		$inte['end'] = $bl - ($bl % 10);
		
		return $inte;
	}

    效果也不盡如人意。。。

 

解決方案3:

    使用真實離散溫度 -》 生成平滑曲線 -》 生成秒級數據

    第一步:去中國天氣網找當地附近一天的真實溫度數據,可惜只有24小時,溫度值還是整數。。。還是整數。。。還是整數。。。

    

 

    第二步:輸入到excel中,適當的手工和修改一下小數點后的數據,模擬畫個圖,基本真實吧。

      

 

    第三步:在excel中,將0、1、2、替換成一天的秒數,為了連續,將首位從1開始

    

 

    第四步,安裝此函數繪圖神器,Origin Pro,將excel中的數據粘至次神器中,選中A B列並畫直線。

      

           

        

    

    第五步:根據曲線,生成,每秒的數據。(拿箭頭工具選中曲線,然后操作一下菜單)

    

    要生成86400個點,如圖:

    

     

    此時又出現兩列新的數據,這兩列數據就是我們要的每秒的溫度值。

     

 

     將新生成的這兩列數,粘如excel中,round一下,繪圖,和原圖一致,但得到了精確到秒的一天的溫度數據。

    

 

 

 

     問題:得到的溫度曲線還是有點太“光滑了”,使用隨機數波動一下效果也不靠譜。

    

     哪位有更好的模擬方法、精確的模擬算法、更真實的模擬結果 或者 直接有精確到秒的溫度數據 更或者,直接有我這個問題的解決方案,可以給在下指點一二。

    碼字不易,轉載請注明出處,謝謝!    2017-04-22

 

    續:

    使用中又發現一利器,數據點隨意拖動啊!!!太實用了!!!

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM