问题描述:
将从1到n这n个整数围成一个圆环,若其中任意2个相邻的数字相加,结果均为素数,那么这个环就成为素数环。
n=20时,下面的序列就是一个素数环:
1 2 3 4 7 6 5 8 9 10 13 16 15 14 17 20 11 12 19 18
php版本回溯算法:
1 <?php 2 //素数环问题 3 include "show.php"; 4 5 define("LEN", 20); 6 7 class Primes 8 { 9 private $initial_data;// array 排序的原始数据 1~n 10 private $ring_data;//array 素数环的结果 11 12 /** 13 * 初始化数据 14 */ 15 public function __construct() 16 { 17 $this->ring_data = array_fill(0, LEN, 0); 18 19 /** 20 * 设置素数环的第一位,默认为1 21 */ 22 $this->ring_data[0] = 1; 23 24 $this->initial_data = range(1, LEN); 25 } 26 27 /** 28 * 获取素数环 29 */ 30 public function get_primes() 31 { 32 $prime = $this->prime_ring($this->initial_data, 1); 33 if ($prime) 34 { 35 return $this->ring_data; 36 } else { 37 return [];//1~LEN之前不存在素数环 38 } 39 } 40 41 /** 42 * 执行核心代码, 计算得出素数环的顺序 43 * $initial_data array 排序的原始数据 44 * $number int 计算到第几位素数 45 */ 46 private function prime_ring($initial_data, $number = 1) 47 { 48 if(!is_numeric($number) || $number < 1) return false; 49 50 if($number == LEN) return $this->is_primes($this->ring_data[($number - 1)], $this->ring_data[0]); 51 52 for($i = 1; $i < LEN; ++$i) 53 { 54 if(isset($initial_data[$i]) && $this->is_primes($initial_data[$i], $this->ring_data[$number - 1]) ) 55 { 56 $this->ring_data[$number] = $initial_data[$i]; 57 unset($initial_data[$i]); 58 59 if($this->prime_ring($initial_data, $number + 1)) 60 { 61 return true; 62 } 63 else 64 { //如果下一个不行, 就回溯到本次 65 $initial_data[$i] = $this->ring_data[$number]; 66 } 67 } 68 } 69 70 return false; 71 } 72 73 74 /** 75 * 判断两数之和是否为素数 76 * $num1 int 77 * $num2 int 78 */ 79 private function is_primes($num1, $num2) 80 { 81 if($num1 <= 0 || $num2 <= 0) return false; 82 if(!is_int($num1) || !is_int($num2)) return false; 83 84 $sum_num = $num1 + $num2; 85 $sqrt_num = sqrt($sum_num); 86 $flag_status = true; 87 for($i = 2; $i <= $sqrt_num; $i++) 88 { 89 $flag_status = ($sum_num % $i == 0) ? false : true; 90 if (!$flag_status) 91 { 92 break; 93 } 94 } 95 return $flag_status; 96 } 97 } 98 99 $p = new Primes(); 100 $res = $p->get_primes(); 101 if (empty($res)) 102 { 103 echo "1 ~ " . LEN . " 不存在素数环!"; 104 } else { 105 show($res); 106 }
结果截图: