探索并优化组合算法中从n个元素里不重复选取m个元素有多少种的的01移位转换法(非递归)

baidu_38487648 2017-05-24 11:31:27
//今天来讲讲如何把逐步优化串行(单机处理)的组合算法--01移位法
//以下所有方法只针对数组下标处理,与数组具体有什么元素没有任何关
//系,所有方法均返回相同的组合数结果集(不输出)
//可能有些同学不知道什么是01移位法,以下作简单的说明:
//首先我们建立一个长度的5的数组来映射它的位置,并用0或1表示该位
//置上的元素是否被选到,比如[1,1,1,0,0]这个序列表示[0,1,2],
//[0,1,1,1,0]则表示[1,2,3];
//下一个序列,总有当前的序列产生,它的产生规律如下:初始化第
//从左向右找到第一对'10',交换他们的值,即'10'=>'01',然后将它们
//前面的'1'全部移动到序列的开头,就产生了一个新的序列,新序列依照
//前面的变化规律产生下一个新的序列,如5选3,变化规律如下
/**
*1 1 1 0 0 //1,2,3
* 1 1 0 1 0 //1,2,4
* 1 0 1 1 0 //1,3,4
* 0 1 1 1 0 //2,3,4
* 1 1 0 0 1 //1,2,5
* 1 0 1 0 1 //1,3,5
* 0 1 1 0 1 //2,3,5
* 1 0 0 1 1 //1,4,5
* 0 1 0 1 1 //2,4,5
* 0 0 1 1 1 //3,4,5
*
* 然后我们来实现第一个版本的01移位法
* @param array $count [数组长度]
* @param int $selectMany [选择多少个]
* @return [mixed] [成功则返回形
* 如[1,1,1,0,0]的组合数结果集(二维数组)]
*/
public function combinationsByTransform1(int $count,int$selectMany){
if($selectMany<2 || $count<$selectMany) return false;
$combination = []; //each combination
for ($i=0; $i < $count; ++$i) {
$combination[] = 0;
}
//init the first combination 初始化第一个序列
for ($i=0; $i < $selectMany ; ++$i) {
$combination[$i] = 1;
}
$transform = [$combination]; //store combination 保存第一个序列
$end = $count-1; //如果i移动到序列末端,未找到'10'则已经产生了所有序列
for ($i=0,$one=-1;$i<$end; ++$i) {
if($combination[$i]) ++$one; //统计直到当前位置,'1'的个数
//找到第一对'10'并交换
if($combination[$i]==1 && $combination[$i+1]==0){
$combination[$i] =0;
$combination[$i+1] = 1;
//以下两个for是把第一对'10'前的'1'全部移动到序列开头
for ($k=0; $k < $one; ++$k) {
$combination[$k] = 1;
}
for ($k=$one; $k < $i; ++$k) {
$combination[$k] = 0;
}
//保存序列
$transform[] = $combination;
//查找下一个序列
$i=-1;
$one = -1;
}
}
//返回组合数形如[1,1,1,0,1]结果集
return $transform;

}
/**combinationsByTransform1 返回的形式如[1,1,1,0,1]
//要没被选择到的位置,而且版本1还浪费空间,故而时间上也会很有影响
//所以我们将版本1改了一下,让其返回形如[0,1,2,3]组合数,这正是
//我们需要的结果
* [combinationsByTransform2 01转换法的改进版,输出组合
* 数形如[0,1,2,3]的结果集]
* @param int $count [同上]
* @param int $selectMany [同上]
* @return [mixed] [返回组合数结果集]
*/
public function combinationsByTransform2(int $count,int$selectMany){
if($selectMany<2 || $count<$selectMany) return false;
$combination = []; //each combination
for ($i=0; $i < $count; ++$i) {
$combination[] = 0;
}
//init the first combination
for ($i=0,$transform=[]; $i < $selectMany ; ++$i) {
$combination[$i] = 1;
$transform [] = $i;
}
$combinations = [$transform];
$end = $count-1;
for ($i=0,$one=-1;$i<$end; ++$i) {
if($combination[$i]) ++$one;
if($combination[$i]==1 && $combination[$i+1]==0){
$combination[$i] =0;
$combination[$i+1] = 1;
for ($k=0; $k < $one; ++$k) {
$combination[$k] = 1;
}
for ($k=$one; $k < $i; ++$k) {
$combination[$k] = 0;
}
//与版本1不一样的地方,这里将序列转换成了形如[1,2,3]的组合数
for ($k=0,$transform = []; $k < $count; ++$k) {
if($combination[$k]) $transform[] = $k;
}
$combinations[] = $transform;
$i=-1;
$one = -1;
}
}
return $combinations;
}

//版本2虽然返回了我们需要的结果,并且大大降低了空间的使用,但是
// 转换过程又遍历了一次,也就是说又花了一次遍历的时间
// 如果序列长度很大,就相当影响性能了,所以需要优化
/**版本3:在版本2的基础上,优化转换过程,使用索引映射和反索引映射,
//可去掉版本2中用于转换的遍历过程
* [combinationsByTransform3 based on combinationsByTransform2
* ,deleting the transform process by using an index(report all
location is the No.x '1') ]
* @param int $count [description]
* @param int $selectMany [description]
* @return [type] [description]
*/
public function combinationsByTransform3(int $count,int$selectMany){
if($selectMany<2 || $count<$selectMany) return false;
$combination = []; //each combination
for ($i=0; $i < $count; ++$i) {
$combination[] = 0;
}
//init the first combination
for ($i=0,$index=[]; $i < $selectMany ; ++$i) {
$combination[$i] = 1;
$index[] = $i; //初始态时每个'1'所在的位置,即第几个再原数组的第几个位置上
}
$reverse = $index; //初始态时原数组中某个'1'是第几个'1',
//与$index互相映射$reverse[$j] = $i,则$index[$i] = $j,
//$j表示原数组的$j下标,$i表示第$i个1;
$combinations = [$index];
$end = $count-1;
for ($i=0,$one=-1;$i<$end; ++$i) {
if($combination[$i]) ++$one;
if($combination[$i]==1 && $combination[$i+1]==0){
$combination[$i] =0;
$combination[$i+1] = 1;
$index[$reverse[$i]] = $i+1; //更新第$i个1的位置信息
$reverse[$i+1] = $reverse[$i]; //更新原数组第$i+1的位置上的对应的第$i个1的位置
unset($reverse[$i]);
//以下两个for将第一对10前的1全部移动到序列开头,并更新相应的$index和$reverse
for ($k=$one; $k < $i; ++$k) {
$combination[$k] = 0;
if(isset($reverse[$k])) unset($reverse[$k]);
}
for ($k=0; $k < $one; ++$k) {
$combination[$k] = 1;
$reverse[$k] = $k;
$index[$k] = $k;
}
$combinations[] = $index; //保存该组合数 $index表示[1,2,3]这样的一维数组
$i=-1;
$one = -1;
}
}
return $combinations;
}

/**虽然版本3比版本2少作了转换过程的遍历,性能也提高了不少,
但是它在每次产生新序列的过程中都遍历了长度为$count的序列,如果,
这个长度非常非常长的长,将严重影响产生新序列的效率
我们来重新理解01移位法的规则:"从前向后找到第一对'10',交换它们",
这句话如果换种理解就是,从前向后遍历所有的1,一旦遍历到的1,如果它
的后一位是0的话,则交换它们,这样我们每产生一个新的序列,最多需要
遍历$selectMany次,如果$count>>$selectMany ,这一步优化的影
响尤为显著,以下是实现这一优化的版本4
* [combinationsByTransform4 based on combinationsByTransform3 ,
* change the max searching lenght of find first '10' from $count
* to $selectMany]
* @param int $count [description]
* @param int $selectMany [description]
* @return [mixed] [description]
*/
public function combinationsByTransform4(int $count,int$selectMany){
if($selectMany<2 || $count<$selectMany) return false;
$combination = []; //each combination
for ($i=0; $i < $count; ++$i) {
$combination[] = 0;
}
//init the first combination
for ($i=0,$index=[]; $i < $selectMany ; ++$i) {
$combination[$i] = 1;
$index[] = $i;
}
$reverse = $index;
$combinations = [$index];
//与版本3不一样的地方只有这里改成了对所有的1遍历,省去了对0的遍历
for ($i=0,$one=-1;$i<$selectMany; ++$i) {
$j = $index[$i]; //$j表示每个1在原序列中的位置
++$one; //计算1的遍历次数,表示到目前为止已经出现这么多个1
//以下同版本3
if($combination[$j]==1 && $j+1<$count &&$combination[$j+1]==0){
$combination[$j] =0;
$combination[$j+1] = 1;
$index[$reverse[$j]] = $j+1;
$reverse[$j+1] = $reverse[$j];
unset($reverse[$j]);
for ($k=$one; $k < $j; ++$k) {
$combination[$k] = 0;
if(isset($reverse[$k])) unset($reverse[$k]);
}
for ($k=0; $k < $one; ++$k) {
$combination[$k] = 1;
$reverse[$k] = $k;
$index[$k] = $k;
}
$combinations[] = $index;
$i=-1;
$one = -1;
}
}
return $combinations;
}
...全文
389 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
荒野鬼舞 2019-03-05
  • 打赏
  • 举报
回复
@Test public void testMethod2() throws InterruptedException{ int[] num=new int[]{1,2,3}; int maxSize = 11; List<String> numList = new ArrayList<String>(); while(num[0]<= maxSize-(num.length-1)){ boolean isRepeat = true; end:for(int i=0;i<num.length;i++){ if(num[i]>maxSize){ isRepeat = false; break end; } } if(isRepeat){ System.out.println(Arrays.toString(num)); numList.add(Arrays.toString(num)); } num[num.length-1]+=1; end:for(int i=0;i<num.length;i++){ int maxbyIndex = maxSize-(num.length-i-1); if(num[i] > maxbyIndex){ num[i-1] +=1; num[i] = num[i-1]+1; int z = num[i]+1; for(int y = i+1;y<num.length;y++){ num[y] = z; z++; } break end; } } } System.out.println("组合数:"+numList.size()); }
baidu_38487648 2017-05-25
  • 打赏
  • 举报
回复

      /**写完了版本5,测试时发现,版本5在n比较大的情况下,
      依然效率低下,原因在于移位过程中,将1转化为0时,遍历
      不少不需要转换的位置,为此,我在版本5的基础上做了一个
      优化的版本6,这个版本的优化的特点在于:把第一对10前所
      有的1移到序列开头的同时,并把原来的位置上的置设为0,删
      除对应的反索引
        * [combinationsByTransform6 based on combinationsByTransform5]
        * @param  int    $count      [description]
        * @param  int    $selectMany [description]
        * @return [mixed]             [description]
        */
       public  function combinationsByTransform6(int $count,int$selectMany){
            if($selectMany<2 || $count<$selectMany) return false;
            $combination = [];  //each combination
            for ($i=0; $i < $count; ++$i) { 
                   $combination[] = 0;
            }
            //init the first combination
            for ($i=0,$index=[]; $i < $selectMany ; ++$i) { 
                   $combination[$i] = 1;
                   $index[] = $i;
            }
            $stackLenght = 0; //栈的初始长度
            $stack = [$selectMany-1]; //第一对'10'中'1'的的位置
            $reverse = $index;
            $combinations = [$index];
            while ($stackLenght>=0) {
                //出栈:该序列从前往后数的第一对'10'中'1'的位置
                $curIndex = $stack[$stackLenght]; 
                unset($stack[$stackLenght]);
                --$stackLenght; //栈的长度减1
                $combination[$curIndex] = 0;
                $combination[$curIndex+1] = 1;
                if($curIndex+2<$count && $combination[$curIndex+2]==0)
                //进栈:下一对'10'中'1'的位置
                      $stack[++$stackLenght] = $curIndex+1;
                $index[$reverse[$curIndex]] = $curIndex+1;
                $reverse[$curIndex+1] = $reverse[$curIndex];
                 $one = $reverse[$curIndex];
                unset($reverse[$curIndex]);
                //以下是把当前位置前面的1移动到开头
               for ($k=0; $k < $one; ++$k) { 
                   $combination[$index[$k]] = 0;
                   if(isset($reverse[$index[$k]])) unset($reverse[$index[$k]]);
                   $combination[$k] = 1;
                   $reverse[$k] = $k;
                   $index[$k] = $k;
               }
               if($combination[$one]==0 && $one-1>=0) 
                    //进栈:下一对'10'中'1'的位置
                    $stack[++$stackLenght] = $one-1;
               $combinations[] = $index;
            }
         return $combinations;
     }
     //后记:虽然我把01移位法优化到了每产生一个组合数只需要
     //O(m)的时间复杂度,实际上上面每个版本的性能并非线性
     //增强,它与n、m的大小关系密切,比如4有时比5性能要高,5有
     //时性能比6要高,但是无论哪个版本它都比不上另一种算法,无论
     //是时间复杂度还是空间复杂度,都比不上,更好的组合算法请查看
     //分治位偏移法(每产生一个组合数只需要O(1)的时间复杂度)
     //以及另一种同样高效的动态建模法
动态建模法 分治位偏移量法
baidu_38487648 2017-05-24
  • 打赏
  • 举报
回复
       /**乍看一下,版本4似乎已经逆天了,其每产生一个新的组合数最多只需要O(m)
       的时间复杂度,m表示选多少个元素,但是它还不能得瑟得太早,版本5表示我要和
       版本4谈人生在实现版本5之前,我们再来看01移位法的规则:"从前向后找到第一
       对'10',交换它们",我们把这句话先多读几遍,有木有明白它的本质?
       木有的话,也没关系,我来解释给你听:它想说的是,定位到从前向后数的第一对'10'
       ,然后交换它们。没错,就是定位,精确的定位,无须任何的遍历!一针见血!
       直接找到第一对'10'。
        既然要做到定位,那我们总得知道第一对'10'的位置在哪吧,也就是说,我们需要
        一个栈去记录它们的位置信息,
        以下的版本5使得每一个组合数的生成只需要O(1)的时间复杂度。
        * [combinationsByTransform5 based on combinationsByTransform4 ,
        * plus accurate locating method which can quickly get the index
        *  of '10' without traversal]
        * @param  int    $count      [description]
        * @param  int    $selectMany [description]
        * @return [type]             [description]
        */
       public  function combinationsByTransform5(int $count,int$selectMany){
            if($selectMany<2 || $count<$selectMany) return false;
            $combination = [];  //each combination
            for ($i=0; $i < $count; ++$i) { 
                   $combination[] = 0;
            }
            //init the first combination
            for ($i=0,$index=[]; $i < $selectMany ; ++$i) { 
                   $combination[$i] = 1;
                   $index[] = $i;
            }
            $stackLenght = 0; //栈的初始长度
            $stack = [$selectMany-1]; //第一对'10'中'1'的的位置
            $reverse = $index;
            $combinations = [$index];
            while ($stackLenght>=0) {
                //出栈:该序列从前往后数的第一对'10'中'1'的位置
                $curIndex = $stack[$stackLenght]; 
                unset($stack[$stackLenght]);
                --$stackLenght; //栈的长度减1
                $combination[$curIndex] = 0;
                $combination[$curIndex+1] = 1;
                if($curIndex+2<$count && $combination[$curIndex+2]==0)
                //进栈:下一对'10'中'1'的位置
                      $stack[++$stackLenght] = $curIndex+1;
                $index[$reverse[$curIndex]] = $curIndex+1;
                $reverse[$curIndex+1] = $reverse[$curIndex];
                 $one = $reverse[$curIndex];
                unset($reverse[$curIndex]);
                //以下两个for是把当前位置前面的1移动到开头
               for ($k=$one; $k < $curIndex; ++$k) { 
                   $combination[$k] = 0;
                   if(isset($reverse[$k])) unset($reverse[$k]);
               }
               for ($k=0; $k < $one; ++$k) { 
                   $combination[$k] = 1;
                   $reverse[$k] = $k;
                   $index[$k] = $k;
               }
               if($combination[$one]==0 && $one-1>=0) 
                    //进栈:下一对'10'中'1'的位置
                    $stack[++$stackLenght] = $one-1;
               $combinations[] = $index;
            }
         return $combinations;
     }
     //后记:虽然我把01移位法优化到了每产生一个组合数只需要O(1)的时间复杂度,
     //但是它依然比不上另一种算法,无论是时间复杂度还是空间复杂度,都比不上另一个组合算法,更好的组合算法请查看
     [分治位偏移法](http://blog.csdn.net/baidu_38487648/article/details/72654987)
如果大家对此算法还有更好的优化方法,欢迎交流!
第 1 章 软件包的安装和介绍....................1 1.1 Python 简介......................................1 1.2 安装软件包......................................2 1.2.1 Python(x,y)..................................... 2 1.2.2 Enthought Python Distribution (EPD)............................................. 3 1.3 方便的开发工具..............................3 1.3.1 IPython........................................... 4 1.3.2 Spyder............................................ 8 1.3.3 Wing IDE 101..............................12 1.4 函数库介绍....................................13 1.4.1 数值计算库.................................13 1.4.2 符号计算库.................................14 1.4.3 界面设计.....................................14 1.4.4 绘图与可视化 .............................14 1.4.5 图像处理和计算机视觉..............15 第 2 章 NumPy——快速处理数据.......... 16 2.1 ndarray 对象...................................16 2.1.1 创建数组.....................................16 2.1.2 存取元素.....................................21 2.1.3 多维数组.....................................24 2.1.4 结构数组.....................................29 2.1.5 内存结构.....................................32 2.2 ufunc 运算......................................35 2.2.1 四则运算.....................................37 2.2.2 比较和布尔运算 .........................39 2.2.3 自定义 ufunc 函数 ......................40 2.2.4 广播.............................................42 2.2.5 ufunc 函数的方法.......................46 2.3 多维数组的下标存取....................48 2.3.1 下标对象.....................................48 2.3.2 整数数组作为下标.....................49 2.3.3 一个复杂的例子.........................51 2.3.4 布尔数组作为下标.....................53 2.4 庞大的函数库 ............................... 54 2.4.1 求和、平均值、方差.................54 2.4.2 最值和排序.................................55 2.4.3 多项式函数.................................57 2.4.4 分段函数.....................................60 2.4.5 统计函数.....................................62 2.5 线性代数 ....................................... 65 2.5.1 各乘积运算.............................65 2.5.2 解线性方程组.............................67 2.6 掩码数组 ....................................... 69 2.7 文件存取 ....................................... 72 2.8 内存映射数组 ............................... 75 第 3 章 SciPy——数值计算库.................79 3.1 常数和特殊函数 ........................... 79 3.2 优化——optimize .......................... 81 3.2.1 最小二乘拟合.............................81 3.2.2 函数最小值.................................84 3.2.3 非线性方程组求解.....................86 3.3 插值——interpolate ....................... 88 3.3.1 B 样条曲线插值..........................88 3.3.2 外推和 Spline 拟合.....................90 3.3.3 二维插值.....................................91 3.4 数值积分——integrate .................. 93 3.4.1 球的体积.....................................93 3.4.2 解常微分方程组.........................95 3.5 信号处理——signal....................... 97 欢迎加入非盈利Python学习交流编程QQ群783462347,群免费提供500+本Python书籍! VIII Python 科学计算 目 录 3.5.1 值滤波.....................................97 3.5.2 滤波器设计.................................98 3.6 图像处理——ndimage .................100 3.6.1 膨胀和腐蚀...............................101 3.6.2 Hit 和 Miss.................................102 3.7 统计——stats................................105 3.7.1 连续和离散概率分布................105 3.7.2 二项、泊松、伽玛分布............108 3.8 嵌入 C 语言程序——weave ........112 第 4 章 SymPy——符号运算好帮手 .... 115 4.1 从例子开始..................................115 4.1.1 封面上的经典公式....................115 4.1.2 球体体积...................................117 4.2 数学表达式..................................119 4.2.1 符号...........................................119 4.2.2 数值...........................................121 4.2.3 运算符和函数 ...........................122 4.3 符号运算......................................125 4.3.1 表达式变换和化简....................125 4.3.2 方程...........................................128 4.3.3 微分...........................................129 4.3.4 微分方程...................................130 4.3.5 积分...........................................131 4.4 其他功能......................................133 4.4.1 平面几何...................................133 4.4.2 绘图...........................................135 第 5 章 matplotlib——绘制精美 的图表..................................... 139 5.1 快速绘图......................................139 5.1.1 使用 pyplot 模块绘图...............139 5.1.2 以面向对象方式绘图................142 5.1.3 配置属性...................................143 5.1.4 绘制多个子图 ...........................145 5.1.5 配置文件...................................147 5.1.6 在图表显示文....................149 5.2 Artist 对象 ................................... 152 5.2.1 Artist 对象的属性.....................154 5.2.2 Figure 容器................................155 5.2.3 Axes 容器..................................156 5.2.4 Axis 容器...................................159 5.2.5 Artist 对象的关系.....................163 5.3 坐标变换和注释 ......................... 164 5.3.1 4 坐标系................................167 5.3.2 坐标变换的步骤.......................169 5.3.3 制作阴影效果...........................173 5.3.4 添加注释...................................174 5.4 绘图函数简介 ............................. 177 5.4.1 对数坐标图...............................177 5.4.2 极坐标图...................................178 5.4.3 柱状图.......................................179 5.4.4 散列图.......................................180 5.4.5 图像...........................................181 5.4.6 等值线图...................................184 5.4.7 三维绘图...................................187 第 6 章 Traits——为 Python 添加类型 定义.........................................190 6.1 开发背景 ..................................... 190 6.2 Trait 属性的功能......................... 192 6.3 Trait 类型对象............................. 196 6.4 Trait 的元数据............................. 198 6.5 预定义的 Trait 类型.................... 200 6.6 Property 属性............................... 204 6.7 Trait 属性监听............................. 206 6.8 Event 和 Button 属性.................. 210 6.9 Trait 属性的从属关系................. 211 6.10 动态添加 Trait 属性.................. 213 6.11 创建自己的 Trait 类型.............. 215 6.11.1 从 TraitType 继承.................215 6.11.2 使用 Trait()............................217 6.11.3 定义 TraitHandler 类.............219 欢迎加入非盈利Python学习交流编程QQ群783462347,群免费提供500+本Python书籍! IX 目 录 第 7 章 TraitsUI——轻松制作用户 界面......................................... 221 7.1 默认界面......................................221 7.2 用 View 定义界面........................222 7.2.1 外部视图和内部视图................222 7.2.2 多模型视图...............................226 7.2.3 Group 对象................................228 7.2.4 配置视图...................................231 7.3 用 Handler 控制界面和模型 .......232 7.3.1 用 Handler 处理事件.................233 7.3.2 Controller 和 UIInfo 对象..........237 7.3.3 响应 Trait 属性的事件..............238 7.4 属性编辑器..................................240 7.4.1 编辑器演示程序 .......................241 7.4.2 对象编辑器...............................243 7.4.3 字符串列表编辑器....................248 7.4.4 对象列表编辑器 .......................250 7.5 菜单、工具条和状态栏..............252 7.6 设计自己的编辑器......................255 7.6.1 Trait 编辑器的工作原理...........255 7.6.2 制作 matplotlib 的编辑器.........259 7.6.3 CSV 数据绘图工具...................262 第 8 章 Chaco——交互式图表............. 264 8.1 面向脚本绘图..............................264 8.2 面向应用绘图..............................265 8.2.1 多条曲线...................................267 8.2.2 Plot 对象的结构........................271 8.2.3 编辑绘图属性 ...........................275 8.2.4 容器(Container).........................276 8.3 添加交互工具..............................279 8.3.1 平移和缩放...............................279 8.3.2 选取范围...................................282 8.3.3 选取数据点...............................284 8.3.4 套索工具...................................287 8.4 二次开发......................................289 8.4.1 用 Kiva 库在数组上绘图..........290 8.4.2 Enable 库的组件.......................292 8.4.3 设计圆形选择工具...................297 8.4.4 制作动画演示...........................301 第 9 章 TVTK——数据的三维可视化....303 9.1 流水线(Pipeline).......................... 304 9.1.1 显示圆锥...................................304 9.1.2 用 ivtk 观察流水线...................307 9.2 数据集(Dataset)........................... 313 9.2.1 ImageData..................................313 9.2.2 RectilinearGrid...........................318 9.2.3 StructuredGrid............................319 9.2.4 PolyData ....................................321 9.3 可视化实例 ................................. 324 9.3.1 切面...........................................325 9.3.2 等值面.......................................330 9.3.3 流线...........................................333 9.4 TVTK 的改进.............................. 337 9.4.1 TVTK 的基本用法....................338 9.4.2 Trait 属性...................................339 9.4.3 序列化(Pickling)........................339 9.4.4 集合迭代...................................340 9.4.5 数组操作...................................341 第 10 章 Mayavi——更方便的可视化....343 10.1 用 mlab 快速绘图 ..................... 343 10.1.1 点和线...................................343 10.1.2 Mayavi 的流水线..................345 10.1.3 二维图像的可视化...............348 10.1.4 网格面...................................352 10.1.5 修改和控制流水线...............356 10.1.6 标量场...................................358 10.1.7 矢量场...................................361 10.2 Mayavi 和 TVTK 之间 的关系....................................... 363 10.2.1 显示 TVTK 流水线..............363 10.2.2 两条流水线之间的关系.......365 欢迎加入非盈利Python学习交流编程QQ群783462347,群免费提供500+本Python书籍! X Python 科学计算 目 录 10.3 Mayavi 应用程序.......................367 10.3.1 操作流水线...........................368 10.3.2 命令行和对象浏览器...........371 10.4 将 Mayavi 嵌入到界面..........374 第 11 章 VPython——制作 3D 演示 动画 ...................................... 378 11.1 场景、物体和照相机................378 11.1.1 控制场景窗口.......................380 11.1.2 控制照相机...........................383 11.1.3 模型的属性...........................384 11.1.4 三维模型...............................387 11.2 制作动画演示............................390 11.2.1 简单动画...............................390 11.2.2 盒子反弹的球...................391 11.3 与场景交互................................393 11.3.1 响应键盘事件.......................394 11.3.2 响应鼠标事件.......................394 11.4 用界面控制场景........................397 11.5 创建复杂模型............................400 11.5.1 faces()的用法........................400 11.5.2 读入模型数据.......................402 第 12 章 OpenCV——图像处理和计算机 视觉 ...................................... 408 12.1 存储图像数据的 Mat 对象........409 12.1.1 Mat 对象和 NumPy 数组.....410 12.1.2 像素点类型...........................414 12.1.3 其他数据类型.......................415 12.1.4 Vector 类型...........................417 12.1.5 在图像上绘图.......................418 12.2 图像处理....................................421 12.2.1 二维卷积...............................421 12.2.2 形态学运算...........................424 12.2.3 填充——floodFill..................426 12.2.4 去瑕疵——inpaint.................427 12.3 图像变换....................................428 12.3.1 几何变换...............................428 12.3.2 重映射——remap..................430 12.3.3 直方图统计...........................433 12.3.4 二维离散傅立叶变换...........437 12.4 图像识别 ................................... 440 12.4.1 用霍夫变换检测直线 和圆.......................................440 12.4.2 图像分割...............................444 12.4.3 用 SURF 进行特征匹配.......450 第 13 章 数据和文件 ............................453 13.1 声音的输入输出 ....................... 453 13.1.1 读写 WAV 文件...................453 13.1.2 用 pyAudio 播放和录音.......456 13.2 视频的输入输出 ....................... 459 13.2.1 读写视频文件.......................459 13.2.2 安装视频编码.......................464 13.3 读写 HDF5 文件....................... 465 13.4 读写 Excel 文件 ........................ 469 13.4.1 写 Excel 文件........................469 13.4.2 读 Excel 文件........................471 第 14 章 数字信号系统.........................473 14.1 FIR 和 IIR 滤波器..................... 473 14.2 FIR 滤波器设计........................ 477 14.2.1 用 firwin()设计滤波器..........479 14.2.2 用 remez()设计滤波器..........481 14.2.3 滤波器的级联.......................483 14.3 IIR 滤波器设计......................... 485 14.3.1 巴特沃斯低通滤波器...........485 14.3.2 双线性变换...........................487 14.3.3 滤波器的频带转换...............490 14.4 数字滤波器的频率响应 ........... 494 14.5 二次均衡滤波器设计工具 ....... 497 14.6 零相位滤波器 ........................... 500 14.7 重取样 ....................................... 501 欢迎加入非盈利Python学习交流编程QQ群783462347,群免费提供500+本Python书籍! XI 目 录 第 15 章 频域信号处理........................ 505 15.1 FFT 演示程序............................505 15.1.1 FFT 知识复习.......................505 15.1.2 合成时域信号.......................509 15.1.3 三角波 FFT 演示程序..........511 15.2 观察信号的频谱........................512 15.2.1 窗函数...................................515 15.2.2 频谱平均...............................517 15.2.3 谱图.......................................519 15.3 卷积运算....................................522 15.3.1 快速卷积...............................522 15.3.2 分段运算...............................524 15.4 信号处理....................................526 15.4.1 基本框架...............................527 15.4.2 频域滤波器...........................528 15.4.3 频率变调处理.......................530 15.4.4 用谱图差减法降噪...............531 15.5 Hilbert 变换................................532 第 16 章 用 C 语言提高计算效率......... 537 16.1 用 ctypes 调用 DLL 库..............537 16.2 用 Weave 嵌入 C++程序...........541 16.2.1 Weave 的工作原理...............541 16.2.2 处理 NumPy 数组.................543 16.2.3 使用 blitz()提速.....................546 16.2.4 扩展模块...............................548 16.3 用 Cython 将 Python 编译 成 C............................................549 16.3.1 编译 Cython 程序.................549 16.3.2 提高计算效率.......................550 16.3.3 快速访问 NumPy 数组.........553 16.4 用 SWIG 创建扩展模块............555 16.4.1 SWIG 的调用方法 和实例 ..................................555 16.4.2 SWIG 基础............................558 16.4.3 SWIG 处理 NumPy 数组......566 第 17 章 自适应滤波器.........................571 17.1 自适应滤波器简介 ................... 571 17.1.1 系统识别...............................571 17.1.2 信号预测...............................572 17.1.3 信号均衡...............................572 17.2 NLMS 计算公式....................... 573 17.3 用 NumPy 实现 NLMS 算法.... 575 17.3.1 系统辨识模拟.......................577 17.3.2 信号均衡模拟.......................579 17.3.3 卷积逆运算...........................581 17.4 用 C 语言加速 NLMS 运算...... 583 17.4.1 用 SWIG 编写扩展模块.......583 17.4.2 用 Weave 嵌入 C++程序......586 第 18 章 单摆和双摆模拟.....................588 18.1 单摆模拟 ................................... 588 18.1.1 小角度时的摆动周期...........589 18.1.2 大角度时的摆动周期...........590 18.2 双摆模拟 ................................... 592 18.2.1 公式推导...............................592 18.2.2 微分方程的数值解...............595 18.2.3 动画演示...............................598 第 19 章 分形几何................................599 19.1 Mandelbrot 集合........................ 599 19.1.1 使用 NumPy 加速计算.........601 19.1.2 使用 Weave 加速计算..........603 19.1.3 连续的逃逸时间...................604 19.1.4 Mandelbrot 演示程序 ...........605 19.2 迭代函数系统(IFS)................... 606 19.2.1 二维仿射变换.......................610 19.2.2 迭代函数系统设计器...........610 19.3 L-System 分形........................... 613 19.4 分形山脉 ................................... 616 19.4.1 一维移位法...................616 19.4.2 二维移位法...................618 19.4.3 菱形方形算法.......................619

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧