精华内容
下载资源
问答
  • N卡A卡之抗锯齿

    千次阅读 2013-08-26 11:33:40
    管理3D设置里的全局设置。 这些就是抗锯齿的选项和功能了.. 一般三重缓冲是开着的   这是我的一般抗锯齿界面..洛奇的话 一般的显卡开16X也没什么问题。但是玩WOW之类的3D游戏的话就只能开小点了,否则很的哦~=。=...
    什么是抗锯齿呢?简单明了地说就是抗图像失真..再简单点说就是在图像中因为分辨问题,边缘难免会出现呈现三角形的锯齿。

    这时候就需要抗锯齿功能了..

    如果你的显卡是英伟达

    那么恭喜

    我和你的显卡一样~英伟达显卡是可以在控制面板里把抗锯齿强行开启的。

    首先你得确保你有显卡的控制面板 如果没有的话去下载一个 http://www.drivergenius.com/

    然后把显卡驱动更新了 .. 重启就有了。

    之后打开NVIDIA控制面板 找到 管理3D设置里的全局设置。

    这些就是抗锯齿的选项和功能了..

    一般三重缓冲是开着的



    N卡A卡之抗锯齿 - Shikamaru - =六道异次元之Ω空间=
     


    这是我的一般抗锯齿界面..洛奇的话 一般的显卡开16X也没什么问题。但是玩WOW之类的3D游戏的话就只能开小点了,否则很卡的哦~=。=

    如果你发现开了以后没什么变化 请关游戏再保存设置.. 如果觉得还是不够明显 那么控制面板里的选项可以试着把异性过滤和平滑设置给关了再

    对比。

    最后ATI..

    我没怎么用过,用过ATI的好像都是在游戏里改抗锯齿。但是本人不怎么喜欢..因为不明显吧..

    如果真的要开那么

    点击右下角的ATI图标或者在桌面上按右键选择CCC选项,选择3D选项,里面的AA、AAA、AF等等便可。

    在级别里面拖动倍数就好了,记得把使用应用程序的勾去掉..

    我知道补丁是可以开

    但是还请喷子自重 这办法对所有的游戏都有效 。

    鉴于7L喷子 我再次声明本帖绝不针对洛奇这一款游戏 。 洛奇N卡开8X也差不多了 再高也没区别了..

    好吧 .. 那么你玩其他游戏去吧 什么3D游戏最明显了~   
    N卡A卡之抗锯齿 - Shikamaru - =六道异次元之Ω空间=
     
    展开全文
  • Vue全局变量校验银行号是否正确

    千次阅读 2019-05-13 14:21:53
    sumOuShu = sumOuShu + parseInt(arrOuShu[n]) } for (let p = 0; p ; p++) { sumJiShuChild1 = sumJiShuChild1 + parseInt(jishuChild1[p]) sumJiShuChild2 = sumJiShuChild2 + parseInt(jishuChild2[p]) } ...

    .定义公共方法,新建一个js文件checkBank.js

    const checkBank = function luhmCheck (bankno) {
      let lastNum = bankno.substr(bankno.length - 1, 1) // 取出最后一位(与luhm进行比较)
      let first15Num = bankno.substr(0, bankno.length - 1) // 前15或18位
      let newArr = []
      for (let i = first15Num.length - 1; i > -1; i--) { // 前15或18位倒序存进数组
        newArr.push(first15Num.substr(i, 1))
      }
      let arrJiShu = [] // 奇数位*2的积 < 9
      let arrJiShu2 = [] // 奇数位*2的积 >9
    
      let arrOuShu = [] // 偶数位数组
      for (let j = 0; j < newArr.length; j++) {
        if ((j + 1) % 2 === 1) { // 奇数位
          if (parseInt(newArr[j]) * 2 < 9) {
            arrJiShu.push(parseInt(newArr[j]) * 2)
          } else {
            arrJiShu2.push(parseInt(newArr[j]) * 2)
          }
        } else {
          arrOuShu.push(newArr[j])
        }// 偶数位
      }
      let jishuChild1 = [] // 奇数位*2 >9 的分割之后的数组个位数
      let jishuChild2 = [] // 奇数位*2 >9 的分割之后的数组十位数
      for (let h = 0; h < arrJiShu2.length; h++) {
        jishuChild1.push(parseInt(arrJiShu2[h]) % 10)
        jishuChild2.push(parseInt(arrJiShu2[h]) / 10)
      }
      let sumJiShu = 0 // 奇数位*2 < 9 的数组之和
      let sumOuShu = 0 // 偶数位数组之和
      let sumJiShuChild1 = 0 // 奇数位*2 >9 的分割之后的数组个位数之和
      let sumJiShuChild2 = 0 // 奇数位*2 >9 的分割之后的数组十位数之和
      let sumTotal = 0
      console.log(sumTotal)
      for (let m = 0; m < arrJiShu.length; m++) {
        sumJiShu = sumJiShu + parseInt(arrJiShu[m])
      }
      for (let n = 0; n < arrOuShu.length; n++) {
        sumOuShu = sumOuShu + parseInt(arrOuShu[n])
      }
      for (let p = 0; p < jishuChild1.length; p++) {
        sumJiShuChild1 = sumJiShuChild1 + parseInt(jishuChild1[p])
        sumJiShuChild2 = sumJiShuChild2 + parseInt(jishuChild2[p])
      }
      // 计算总和
      sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2)
      // 计算Luhm值
      let k = parseInt(sumTotal) % 10 === 0 ? 10 : parseInt(sumTotal) % 10
      let luhm = 10 - k
      if (Number(lastNum) === luhm && lastNum.length !== 0 && bankno.length > 11) {
        return true
      } else {
        return false
      }
    }
    export default checkBank
    

     

    展开全文
  • 前言 Android中虽然可以通过设置 Thread.setDefaultUncaughtExceptionHandler来捕获全局的所有线程的异常,但主线程抛出异常时仍旧会导致activity闪退,app进程重启。使用Cockroach后就可以保证不管怎样抛异常...

    前言

        Android中虽然可以通过设置 Thread.setDefaultUncaughtExceptionHandler来捕获全局的所有线程的异常,但主线程抛出异常时仍旧会导致activity闪退,app进程重启。使用Cockroach后就可以保证不管怎样抛异常activity都不会闪退,app进程也不会重启。

    DefaultUncaughtExceptionHandler使用。

    public class CrashCatchHandler implements UncaughtExceptionHandler {
    
        public static final String TAG = "CrashCatchHandler";
        private static CrashCatchHandler crashHandler = new CrashCatchHandler();
        private Context mContext;
        private UncaughtExceptionHandler mDefaultCaughtExceptionHandler;
    
        /**
         * 饿汉单例模式(静态)
         *
         * @return
         */
        public static CrashCatchHandler getInstance() {
            return crashHandler;
        }
    
        /**
         * 初始化
         *
         * @param context
         */
        public void init(Context context) {
            mContext = context;
            //获取默认的系统异常捕获器
            mDefaultCaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
            //把当前的crash捕获器设置成默认的crash捕获器
            Thread.setDefaultUncaughtExceptionHandler(this);
        }
    
        @Override
        public void uncaughtException(Thread thread, Throwable throwable) {
            if (!handleException(throwable) && mDefaultCaughtExceptionHandler != null) {
                //如果用户没有处理则让系统默认的异常处理器来处理
                mDefaultCaughtExceptionHandler.uncaughtException(thread, throwable);
            }else {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    LogUtils.e(TAG, "error : "+ e);
                }
                //退出程序
                 AppUtil.restarteApp(mContext);
            }
        }
        /**
         * 自定义错误处理
         * @param ex
         * @return true:如果处理了该异常信息;否则返回false
         */
        private boolean handleException(Throwable ex) {
            if (ex == null) {
                return false;
            }
            final String msg = ex.getLocalizedMessage();
            if (msg == null) {
                return false;
            }
    
            //使用Toast来显示异常信息
            new Thread() {
                @Override
                public void run() {
                    Looper.prepare();
                    Toast.makeText(mContext, "很抱歉,程序出现异常!", Toast.LENGTH_LONG).show();
                    Looper.loop();
                }
            }.start();
            return true;
        }
    }
    

    使用很方便,在程序入口,Application类中初始化即可。


    Cockroach 的使用

    自定义Application继承自android的Application,并在Application中装载,越早初始化越好,可以在Aplication的onCreate中初始化,当然也可以根据需要在任意地方(不一定要在主线程)装载,在任意地方卸载。可以多次装载和卸载。

    例如:

    [java]  view plain  copy
    1. import android.app.Application;  
    2. import android.os.Handler;  
    3. import android.os.Looper;  
    4. import android.util.Log;  
    5. import android.widget.Toast;  
    6.   
    7. /** 
    8.  * Created by wanjian on 2017/2/14. 
    9.  */  
    10.   
    11. public class App extends Application {  
    12.   
    13.     @Override  
    14.     public void onCreate() {  
    15.         super.onCreate();  
    16.   
    17.         Cockroach.install(new Cockroach.ExceptionHandler() {  
    18.   
    19.            // handlerException内部建议手动try{  你的异常处理逻辑  }catch(Throwable e){ } ,以防handlerException内部再次抛出异常,导致循环调用handlerException  
    20.   
    21.             @Override  
    22.             public void handlerException(final Thread thread, final Throwable throwable) {  
    23.             //开发时使用Cockroach可能不容易发现bug,所以建议开发阶段在handlerException中用Toast谈个提示框,  
    24.             //由于handlerException可能运行在非ui线程中,Toast又需要在主线程,所以new了一个new Handler(Looper.getMainLooper()),  
    25.             //所以千万不要在下面的run方法中执行耗时操作,因为run已经运行在了ui线程中。  
    26.             //new Handler(Looper.getMainLooper())只是为了能弹出个toast,并无其他用途  
    27.                 new Handler(Looper.getMainLooper()).post(new Runnable() {  
    28.                     @Override  
    29.                     public void run() {  
    30.                         try {  
    31.                         //建议使用下面方式在控制台打印异常,这样就可以在Error级别看到红色log  
    32.                             Log.e("AndroidRuntime","--->CockroachException:"+thread+"<---",throwable);  
    33.                             Toast.makeText(App.this"Exception Happend\n" + thread + "\n" + throwable.toString(), Toast.LENGTH_SHORT).show();  
    34. //                        throw new RuntimeException("..."+(i++));  
    35.                         } catch (Throwable e) {  
    36.   
    37.                         }  
    38.                     }  
    39.                 });  
    40.             }  
    41.         });  
    42.     }  
    43. }  

    载 Cockroach

    [java]  view plain  copy
    1. Cockroach.uninstall();  

    测试

    装载Cockroach后点击view抛出异常和new Handler中抛出异常

    [java]  view plain  copy
    1.         final TextView textView = (TextView) findViewById(R.id.text);  
    2.         findViewById(R.id.install).setOnClickListener(new View.OnClickListener() {  
    3.             @Override  
    4.             public void onClick(View v) {  
    5.                 textView.setText("已安装 Cockroach");  
    6.                 install();  
    7.             }  
    8.         });  
    9.   
    10.         findViewById(R.id.uninstall).setOnClickListener(new View.OnClickListener() {  
    11.             @Override  
    12.             public void onClick(View v) {  
    13.                 textView.setText("已卸载 Cockroach");  
    14.                 Cockroach.uninstall();  
    15.             }  
    16.         });  
    17.   
    18.         findViewById(R.id.but1).setOnClickListener(new View.OnClickListener() {  
    19.             @Override  
    20.             public void onClick(View v) {  
    21.                 throw new RuntimeException("click exception...");  
    22.             }  
    23.         });  
    24.   
    25.         findViewById(R.id.but2).setOnClickListener(new View.OnClickListener() {  
    26.             @Override  
    27.             public void onClick(View v) {  
    28.                 new Handler().post(new Runnable() {  
    29.                     @Override  
    30.                     public void run() {  
    31.                         throw new RuntimeException("handler exception...");  
    32.                     }  
    33.                 });  
    34.             }  
    35.         });  
    36.   
    37.         findViewById(R.id.but3).setOnClickListener(new View.OnClickListener() {  
    38.             @Override  
    39.             public void onClick(View v) {  
    40.                 new Thread() {  
    41.                     @Override  
    42.                     public void run() {  
    43.                         super.run();  
    44.                         throw new RuntimeException("new thread exception...");  
    45.                     }  
    46.                 }.start();  
    47.             }  
    48.         });  
    49.   
    50.         findViewById(R.id.but4).setOnClickListener(new View.OnClickListener() {  
    51.             @Override  
    52.             public void onClick(View v) {  
    53.                 startActivity(new Intent(getApplicationContext(), SecActivity.class));  
    54.             }  
    55.         });  
    56.   
    57.     }  
    58.   
    59.     private void install() {  
    60.         Cockroach.install(new Cockroach.ExceptionHandler() {  
    61.             @Override  
    62.             public void handlerException(final Thread thread, final Throwable throwable) {  
    63.   
    64.                 Log.d("Cockroach""MainThread: " + Looper.getMainLooper().getThread() + "  curThread: " + Thread.currentThread());  
    65.   
    66.                 new Handler(Looper.getMainLooper()).post(new Runnable() {  
    67.                     @Override  
    68.                     public void run() {  
    69.                         try {  
    70.   
    71.                             Log.e("AndroidRuntime","--->CockroachException:"+thread+"<---",throwable);  
    72.                             Toast.makeText(getApplicationContext(), "Exception Happend\n" + thread + "\n" + throwable.toString(), Toast.LENGTH_SHORT).show();  
    73. //                        throw new RuntimeException("..."+(i++));  
    74.                         } catch (Throwable e) {  
    75.   
    76.                         }  
    77.                     }  
    78.                 });  
    79.             }  
    80.         });  
    81.     }  

    捕获到的堆栈如下,可以看到都已经被 at com.wanjian.cockroach.Cockroach$1.run(Cockroach.java:47) 拦截,APP没有任何影响,没有闪退,也没有重启进程

    [java]  view plain  copy
    1. 02-16 09:58:00.660 21199-21199/wj.com.fuck E/AndroidRuntime: --->CockroachException:Thread[main,5,main]<---  
    2.                                                              java.lang.RuntimeException: click exception...  
    3.                                                                  at wj.com.fuck.MainActivity$3.onClick(MainActivity.java:53)  
    4.                                                                  at android.view.View.performClick(View.java:4909)  
    5.                                                                  at android.view.View$PerformClick.run(View.java:20390)  
    6.                                                                  at android.os.Handler.handleCallback(Handler.java:815)  
    7.                                                                  at android.os.Handler.dispatchMessage(Handler.java:104)  
    8.                                                                  at android.os.Looper.loop(Looper.java:194)  
    9.                                                                  at com.wanjian.cockroach.Cockroach$1.run(Cockroach.java:47)  
    10.                                                                  at android.os.Handler.handleCallback(Handler.java:815)  
    11.                                                                  at android.os.Handler.dispatchMessage(Handler.java:104)  
    12.                                                                  at android.os.Looper.loop(Looper.java:194)  
    13.                                                                  at android.app.ActivityThread.main(ActivityThread.java:5826)  
    14.                                                                  at java.lang.reflect.Method.invoke(Native Method)  
    15.                                                                  at java.lang.reflect.Method.invoke(Method.java:372)  
    16.                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1009)  
    17.                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:804)  
    18. 02-16 09:58:12.401 21199-21199/wj.com.fuck E/AndroidRuntime: --->CockroachException:Thread[main,5,main]<---  
    19.                                                              java.lang.RuntimeException: handler exception...  
    20.                                                                  at wj.com.fuck.MainActivity$4$1.run(MainActivity.java:63)  
    21.                                                                  at android.os.Handler.handleCallback(Handler.java:815)  
    22.                                                                  at android.os.Handler.dispatchMessage(Handler.java:104)  
    23.                                                                  at android.os.Looper.loop(Looper.java:194)  
    24.                                                                  at com.wanjian.cockroach.Cockroach$1.run(Cockroach.java:47)  
    25.                                                                  at android.os.Handler.handleCallback(Handler.java:815)  
    26.                                                                  at android.os.Handler.dispatchMessage(Handler.java:104)  
    27.                                                                  at android.os.Looper.loop(Looper.java:194)  
    28.                                                                  at android.app.ActivityThread.main(ActivityThread.java:5826)  
    29.                                                                  at java.lang.reflect.Method.invoke(Native Method)  
    30.                                                                  at java.lang.reflect.Method.invoke(Method.java:372)  
    31.                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1009)  
    32.                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:804)  
    33. 02-16 09:58:13.241 21199-21199/wj.com.fuck E/AndroidRuntime: --->CockroachException:Thread[Thread-26326,5,main]<---  
    34.                                                              java.lang.RuntimeException: new thread exception...  
    35.                                                                  at wj.com.fuck.MainActivity$5$1.run(MainActivity.java:76)  
    36.   
    37. 当卸载Cockroach后再在click中抛出异常,日志如下  
    38.   
    39. 02-16 09:59:01.251 21199-21199/wj.com.fuck E/AndroidRuntime: FATAL EXCEPTION: main  
    40.                                                              Process: wj.com.fuck, PID: 21199  
    41.                                                              java.lang.RuntimeException: click exception...  
    42.                                                                  at wj.com.fuck.MainActivity$3.onClick(MainActivity.java:53)  
    43.                                                                  at android.view.View.performClick(View.java:4909)  
    44.                                                                  at android.view.View$PerformClick.run(View.java:20390)  
    45.                                                                  at android.os.Handler.handleCallback(Handler.java:815)  
    46.                                                                  at android.os.Handler.dispatchMessage(Handler.java:104)  
    47.                                                                  at android.os.Looper.loop(Looper.java:194)  
    48.                                                                  at android.app.ActivityThread.main(ActivityThread.java:5826)  
    49.                                                                  at java.lang.reflect.Method.invoke(Native Method)  
    50.                                                                  at java.lang.reflect.Method.invoke(Method.java:372)  
    51.                                                                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1009)  
    52.                                                                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:804)  

    可以看到 at com.wanjian.cockroach.Cockroach$1.run(Cockroach.java:47) 没有拦截,并且APP crash了。

    注意

    • 当主线程或子线程抛出异常时都会调用exceptionHandler.handlerException(Thread thread, Throwable throwable)

    • exceptionHandler.handlerException可能运行在非UI线程中。

    • handlerException内部建议手动try{ 你的异常处理逻辑 }catch(Throwable e){ } ,以防handlerException内部再次抛出异常,导致循环调用handlerException

    • 若设置了Thread.setDefaultUncaughtExceptionHandler则可能无法捕获子线程异常。

    虽然可以捕获到所有异常,但可能会导致一些莫名其妙的问题,比如view初始化时发生了异常,异常后面的代码得不到执行,虽然不 会导致app crash但view内部已经出现了问题,运行时就会出现很奇葩的现象。再比如activity声明周期方法中抛出了异常,则生 命周期就会不完整,从而导致各种奇葩的现象。

    虽然会导致各种奇葩问题发生,但可以最大程度的保证APP正常运行,很多时候我们希望主线程即使抛出异常也不影响app的正常使用,比如我们 给某个view设置背景色时,由于view是null就会导致app crash,像这种问题我们更希望即使view没法设置颜色也不要crash,这 时Cockroach就可以满足你的需求。

    handlerException(final Thread thread, final Throwable throwable)内部建议请求自己服务器决定该如何处理该异常,是 直接忽略还是杀死APP又或者其他操作。

    Cockroach采用android标准API编写,无依赖,足够轻量,轻量到只有不到100行代码,一般不会存在兼容性问题,也不存在性能上的问题,可以兼容所有android版本。

    已上传到jcenter, compile 'com.wanjian:cockroach:0.0.5'

    原理分析:

    android中最重要的就是Handler机制了,简单来说Handler机制就是在一个死循环内部不断取走阻塞队列头部的Message,这个阻塞队列在主线程中是唯一的,当没有Message时,循环就阻塞,当一旦有Message时就立马被主线程取走并执行Message。

    查看android源码可以发现在ActivityThread中main方法(main方法签名 public static void main(String[] args){},这个main方法是静态的,公有的,可以理解为应用的入口)最后执行了Looper.loop();,此方法内部是个死循环(for(;;)循环),所以一般情况下主线程是不会退出的,除非抛出异常。queue.next();就是从阻塞队列里取走头部的Message,当没有Message时主线程就会阻塞在这里,一有Message就会继续往下执行。android的view绘制,事件分发,activity启动,activity的生命周期回调等等都是一个个的Message,android会把这些Message插入到主线程中唯一的queue中,所有的消息都排队等待主线程的执行。

    ActivityThread的main方法如下:

    [java]  view plain  copy
    1. public static void main(String[] args) {  
    2.           
    3.      ...  
    4.        Looper.prepareMainLooper();//创建主线程唯一的阻塞队列queue  
    5.        ...  
    6.        ActivityThread thread = new ActivityThread();  
    7.        thread.attach(false);//执行初始化,往queue中添加Message等  
    8.        ...  
    9.        Looper.loop();//开启死循环,挨个执行Message  
    10.   
    11.        throw new RuntimeException("Main thread loop unexpectedly exited");  
    12.    }  


    Looper.loop()关键代码如下:

    [java]  view plain  copy
    1. for (;;) {  
    2.          Message msg = queue.next(); // might block  
    3.          ...  
    4.          msg.target.dispatchMessage(msg);//执行Message  
    5.          ...  
    6. }  

    android消息机制伪代码如下:

    [java]  view plain  copy
    1. public class ActivityThread {  
    2.   
    3.     public static void main(String[]args){  
    4.           
    5.         Queue queue=new Queue();// 可以理解为一个加锁的,可以阻塞线程的ArrayList  
    6.           
    7.         queue.add(new Message(){  
    8.             void run(){  
    9.                 ...  
    10.                 print("android 启动了,下一步该往queue中插入启动主Activity的Message了");  
    11.                 Message msg=getMessage4LaunchMainActivity();  
    12.                 queue.add(msg);  
    13.             }  
    14.           
    15.         });  
    16.           
    17.         for(;;){//开始死循环,for之后的代码永远也得不到执行  
    18.             Message  msg=queue.next();  
    19.               
    20.             msg.run();  
    21.         }  
    22.     }  
    23. }  

    看了上面的分析相信大家对android的消息机制很清楚了。 关于Handler机制更多内容可以看这  java工程实现Handler机制代码

    下面我们看一下Cockroach的核心代码

    [java]  view plain  copy
    1.  new Handler(Looper.getMainLooper()).post(new Runnable() {  
    2.             @Override  
    3.             public void run() {  
    4.                //主线程异常拦截  
    5.                 while (true) {  
    6.                     try {  
    7.                         Looper.loop();//主线程的异常会从这里抛出  
    8.                     } catch (Throwable e) {  
    9.                                                   
    10.                     }  
    11.                 }  
    12.             }  
    13.         });  
    14.          
    15.         sUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();  
    16.          //所有线程异常拦截,由于主线程的异常都被我们catch住了,所以下面的代码拦截到的都是子线程的异常  
    17.         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {  
    18.             @Override  
    19.             public void uncaughtException(Thread t, Throwable e) {  
    20.                   
    21.             }  
    22. });  

    原理很简单,就是通过Handler往主线程的queue中添加一个Runnable,当主线程执行到该Runnable时,会进入我们的while死循环,如果while内部是空的就会导致代码卡在这里,最终导致ANR,但我们在while死循环中又调用了Looper.loop(),这就导致主线程又开始不断的读取queue中的Message并执行,这样就可以保证以后主线程的所有异常都会从我们手动调用的Looper.loop()处抛出,一旦抛出就会被try{}catch捕获,这样主线程就不会crash了,如果没有这个while的话那么主线程下次抛出异常时我们就又捕获不到了,这样APP就又crash了,所以我们要通过while让每次crash发生后都再次进入消息循环,while的作用仅限于每次主线程抛出异常后迫使主线程再次进入消息循环。我们可以用下面的伪代码来表示:

    [java]  view plain  copy
    1. public class ActivityThread {  
    2.   
    3.     public static void main(String[]args){  
    4.           
    5.         Queue queue=new Queue();// 可以理解为一个加锁的,可以阻塞线程的ArrayList  
    6.           
    7.         ...  
    8.           
    9.         for(;;){//开始死循环,for之后的代码永远也得不到执行  
    10.             Message  msg=queue.next();  
    11.               
    12.             //如果msg 是我们post的Runnable就会执行如下代码  
    13.                 //我们post的Runnable中的代码  
    14.                   while (true) {  
    15.                     try {  
    16.                          for(;;){//所有主线程的异常都会从msg.run()中抛出,所以我们加一个try{}catch来捕获所有主线程异常,捕获到后再次强迫进入循环,不断读取queue中消息并执行  
    17.                             Message  msg=queue.next();  
    18.                             msg.run();  
    19.                          }  
    20.                          
    21.                     } catch (Throwable e) {  
    22.                       
    23.                     }  
    24.             //否则执行其他逻辑    
    25.         }  
    26.     }  

    为什么要通过new Handler.post方式而不是直接在主线程中任意位置执行 while (true) { try { Looper.loop(); } catch (Throwable e) {} }

    这是因为该方法是个死循环,若在主线程中,比如在Activity的onCreate中执行时会导致while后面的代码得不到执行,activity的生命周期也就不能完整执行,通过Handler.post方式可以保证不影响该条消息中后面的逻辑。


    转自“打不死的小强,永不crash的Android”


    亲测,唯不足之处是,在Activity中的生命周期方法里异常之后,crash到但未能处理Activity,导致假死状态。

    下面贴出code:

    Cockroach:

    [java]  view plain  copy
    1. package com.support.framework.crash;  
    2.   
    3. import android.os.Binder;  
    4. import android.os.Handler;  
    5. import android.os.Looper;  
    6.   
    7. import com.support.BaseApp;  
    8.   
    9. /** 
    10.  * Created by wanjian on 2017/2/14. 
    11.  */  
    12.   
    13. public final class Cockroach {  
    14.   
    15.     public interface ExceptionHandler {  
    16.   
    17.         void handlerException(Thread thread, Throwable throwable);  
    18.     }  
    19.   
    20.     private Cockroach() {  
    21.     }  
    22.   
    23.     private static ExceptionHandler sExceptionHandler;  
    24.     private static Thread.UncaughtExceptionHandler sUncaughtExceptionHandler;  
    25.     private static boolean sInstalled = false;//标记位,避免重复安装卸载  
    26.   
    27.     /** 
    28.      * 当主线程或子线程抛出异常时会调用exceptionHandler.handlerException(Thread thread, Throwable throwable) 
    29.      * <p> 
    30.      * exceptionHandler.handlerException可能运行在非UI线程中。 
    31.      * <p> 
    32.      * 若设置了Thread.setDefaultUncaughtExceptionHandler则可能无法捕获子线程异常。 
    33.      * 
    34.      * @param exceptionHandler 
    35.      */  
    36.     public static synchronized void install(ExceptionHandler exceptionHandler) {  
    37.         if (sInstalled) {  
    38.             return;  
    39.         }  
    40.         sInstalled = true;  
    41.         sExceptionHandler = exceptionHandler;  
    42.   
    43.         new Handler(Looper.getMainLooper()).post(new Runnable() {  
    44.             @Override  
    45.             public void run() {  
    46.   
    47.                 while (true) {  
    48.                     try {  
    49.                         Looper.loop();  
    50.                     } catch (Throwable e) {  
    51. //                        Binder.clearCallingIdentity();  
    52.                         if (e instanceof QuitCockroachException) {  
    53.                             return;  
    54.                         }  
    55.                         if (sExceptionHandler != null) {  
    56.                             //Unable to start activity  
    57.                             sExceptionHandler.handlerException(Looper.getMainLooper().getThread(), e);  
    58. //                            sUncaughtExceptionHandler.uncaughtException(Looper.getMainLooper().getThread(), e);  
    59.                         }  
    60.                     }  
    61.                 }  
    62.             }  
    63.         });  
    64.   
    65.         sUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();  
    66.         Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {  
    67.             @Override  
    68.             public void uncaughtException(Thread t, Throwable e) {  
    69.                 if (sExceptionHandler != null) {  
    70.                     sExceptionHandler.handlerException(t, e);  
    71.                 }  
    72.             }  
    73.         });  
    74.   
    75.     }  
    76.   
    77.     public static synchronized void uninstall() {  
    78.         if (!sInstalled) {  
    79.             return;  
    80.         }  
    81.         sInstalled = false;  
    82.         sExceptionHandler = null;  
    83.         //卸载后恢复默认的异常处理逻辑,否则主线程再次抛出异常后将导致ANR,并且无法捕获到异常位置  
    84.         Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);  
    85.         new Handler(Looper.getMainLooper()).post(new Runnable() {  
    86.             @Override  
    87.             public void run() {  
    88.                 throw new QuitCockroachException("Quit Cockroach.....");//主线程抛出异常,迫使 while (true) {}结束  
    89.             }  
    90.         });  
    91.   
    92.     }  
    93. }  

    QuitCockroachException:

    [java]  view plain  copy
    1. package com.support.framework.crash;  
    2.   
    3. /** 
    4.  * Created by wanjian on 2017/2/15. 
    5.  */  
    6.   
    7. final class QuitCockroachException extends RuntimeException {  
    8.     public QuitCockroachException(String message) {  
    9.         super(message);  
    10.     }  
    11. }  


    展开全文
  • 【最优化导论】全局搜索算法

    千次阅读 2019-08-22 23:08:45
    全局搜索算法 1. 引言 全局意义上的搜索方法能够在整个可行集上开展搜索,以找到极小点。这些方法只需要计算函数目标值...在此方法中引入了“单纯形”的概念,单纯形指的是在n维空间中选取n+1个点(p0,p1,⋯&Th...

    全局搜索算法

    1. 引言

    全局意义上的搜索方法能够在整个可行集上开展搜索,以找到极小点。这些方法只需要计算函数目标值,不需要对目标函数进行求导。这类方法的适用面更加广阔,在某些情况下,这些方法产生的解可以作为如梯度方法、牛顿法等迭代方法的“较好”的初始点。

    2. Melder-Mead 单纯形法

    在此方法中引入了“单纯形”的概念,单纯形指的是在n维空间中选取n+1个点( p 0 , p 1 , ⋯ &ThinSpace; , p n \mathbf{p_0}, \mathbf{p_1}, \cdots , \mathbf{p_n} p0,p1,,pn)所组成的几何形状,需要满足:

    d e t = [ p 0 p 1 ⋯ p n 1 1 ⋯ 1 ] ≠ 0 det=\begin{bmatrix} \mathbf{p_0} &amp; \mathbf{p_1} &amp; \cdots &amp; \mathbf{p_n} \\ 1 &amp; 1 &amp; \cdots &amp; 1 \\ \end{bmatrix}\neq 0 det=[p01p11pn1]̸=0

    通俗来讲,这个条件要求在 R \mathbb{R} R中,两个点不重合;在 R 2 \mathbb{R}^2 R2中,3个点不共线;在 R 3 \mathbb{R}^3 R3中,4个点不共面。也就是说,单纯形包围的n维空间具有有限的体积。

    2.1 基本思想

    针对 f ( x ) , x ∈ R n f( \mathbf{x}),\mathbf{x}\in \mathbb{R}^n f(x),xRn的最小化问题,首先需要选择n+1个点构成单纯形。具体选择方法为先选择初始点 x ( 0 ) = p 0 \mathbf{x}^{(0)}=\mathbf{p_0} x(0)=p0,然后在按照如下方式产生其他点:

    p i = p 0 + λ i e i \mathbf{p}_i=\mathbf{p}_0+\lambda_i\mathbf{e}_i pi=p0+λiei

    其中 e i \mathbf{e}_i ei为空间中的标准基, λ i \lambda_i λi为正数,按照优化问题的规模确定其大小。选择n+1个点之后就可以构成单纯形了。

    单纯形确定之后就可以通过不断迭代,使得单纯形能够朝着函数的极小点收敛。对于函数最小化的优化问题而言,目标函数值最大的点将被另外的点代替,持续迭代之后,直到单纯形收敛到目标函数的极小点。

    下面具体到二维问题来说明点的替换规则。

    2.2 举例:二维问题

    在二维问题中,我们需要选择3个点来构成单纯形,因为需要比较对应目标函数值的大小,所以需要对每个点对应的函数值进行排序。令 p l , p n l , p s \mathbf{p}_l,\mathbf{p}_{nl},\mathbf{p}_s pl,pnl,ps分别表示对应函数值最大、次大和最小的点。

    在n维为中计算最好的n个点(扣除了最差的点)的重心 p g \mathbf{p}_g pg

    p g = ∑ i = 0 n − 1 p i n \mathbf{p}_g=\sum^{n-1}_{i=0}\frac{\mathbf{p}_i}{n} pg=i=0n1npi

    在二维问题中,最好点和次好点的重心为:

    p g = 1 2 ( p n l + p s ) \mathbf{p}_g=\frac{1}{2}(\mathbf{p}_{nl}+\mathbf{p}_s) pg=21(pnl+ps)

    利用 p g \mathbf{p}_g pg进行反射操作,反射系数 ρ &gt; 0 \rho&gt;0 ρ>0,在 p g \mathbf{p}_g pg方向上对最差点 p l \mathbf{p}_l pl进行反射,得到反射点 p r \mathbf{p}_r pr

    p r = p g + ρ ( p g − p l ) \mathbf{p}_r=\mathbf{p}_g+\rho(\mathbf{p}_g-\mathbf{p}_l) pr=pg+ρ(pgpl)

    然后根据 p r \mathbf{p}_r pr的取值情况,再决定怎么取代最差点 p l \mathbf{p}_l pl

    反射系数一般令 ρ = 1 \rho=1 ρ=1,反射过程如图所示:

    [外链图片转存失败(img-8ccZPvvS-1566486265974)(assets/1564471545198.png)]

    1)若 f ( p s ) &lt; f ( p r ) &lt; f ( p n l ) f(\mathbf{p}_s)&lt;f(\mathbf{p}_r)&lt;f(\mathbf{p}_{nl}) f(ps)<f(pr)<f(pnl)

    反射出来的点对应的函数值小于原来次大的函数值,说明反射是成功的,则利用 p r \mathbf{p}_r pr代替原来的 p l \mathbf{p}_l pl

    2)若 f ( p r ) &lt; f ( p s ) f(\mathbf{p}_r)&lt;f(\mathbf{p}_s) f(pr)<f(ps)

    反射出来的点都比原来的最小值的点都要小,说明反射的太成功了,说明反射的方向很好,此时尝试再延伸,看看会不会有更好的结果:

    [外链图片转存失败(img-54cR9WMP-1566486265974)(assets/1564471939912.png)]

    p e = p g + χ ( p r − p g ) \mathbf{p}_e=\mathbf{p}_g+\chi (\mathbf{p}_r-\mathbf{p}_g) pe=pg+χ(prpg),其中 χ &gt; 1 \chi&gt;1 χ>1

    • 如果 f ( p e ) &lt; f r f(\mathbf{p}_e)&lt;f_r f(pe)<fr:延伸正确,用 p e \mathbf{p}_e pe代替原来的 p l \mathbf{p}_l pl
    • 如果 f e ≥ f r f_e \geq f_r fefr:延伸出来的点对应的函数值大于原来的,不能延伸了,直接用 p r \mathbf{p}_r pr代替原来的 p l \mathbf{p}_l pl

    3)若 f ( p r ) ≥ f ( p n l ) f(\mathbf{p}_r)\geq f(\mathbf{p}_{nl}) f(pr)f(pnl)

    反射出来的点对应的函数值比原来次差的点要差,此时产生两种情况,一种是比原来最差的点要更差,另一种是介于次差点和最差点中间。

    • f ( p n l ) ≤ f ( p r ) &lt; f ( p l ) f(\mathbf{p}_{nl})\leq f(\mathbf{p}_r)&lt; f(\mathbf{p}_l) f(pnl)f(pr)<f(pl):

      进行外收缩,令 p c = p g + γ ( p r − p g ) \mathbf{p}_c=\mathbf{p}_g+\gamma (\mathbf{p}_r-\mathbf{p}_g) pc=pg+γ(prpg),其中 0 &lt; γ &lt; 1 0&lt;\gamma&lt;1 0<γ<1

      [外链图片转存失败(img-JDqKHizc-1566486265976)(assets/1564472799328.png)]

    • f ( p r ) ≥ f ( p l ) f(\mathbf{p}_r)\geq f(\mathbf{p}_l) f(pr)f(pl)

      反射出来的点成为了最差点,进行内收缩,令 p c = p g + γ ( p l − p g ) \mathbf{p}_c=\mathbf{p}_g+\gamma (\mathbf{p}_l-\mathbf{p}_g) pc=pg+γ(plpg)

      [外链图片转存失败(img-QfJ2eBTF-1566486265976)(assets/1564473071647.png)]

    接着要对 p c \mathbf{p}_c pc进行判断:

    • f c ≤ f l f_c\leq f_l fcfl:说明收缩以后比原来来最差点对应的值要小了,即收缩成功,用 p c \mathbf{p}_c pc代替 p l \mathbf{p}_l pl

    • f c &gt; f l f_c&gt;f_l fc>fl:说明收缩失败了,那就在原来的3个点中,只保留 p s \mathbf{p}_s ps, p s \mathbf{p}_s ps与其它点距离减半:

      [外链图片转存失败(img-i8QAat3A-1566486265976)(assets/1564473310218.png)]

      进行这种压缩方式之后,在新的3个点中再进行上述的操作。

    以上就是在二维问题中,Melder-Mead 单纯形法的搜索和迭代过程。

    下图列举了一个利用Melder-Mead 单纯形法求救二元函数极小点的部分搜索过程:

    [外链图片转存失败(img-Ld1lzHtY-1566486265977)(assets/1564473527210.png)]

    3. 模拟退火算法

    3.1 随机搜索

    模拟退火法是一种随机搜索算法,随机搜索算法是一种能够在优化问题的可行集中随机采样,逐步完成搜索的方法。

    m a x i m i z e      f ( x ) s u b j e c t    t o    x ∈ Ω \begin{aligned} maximize\ \ \ \ f(\mathbf{x}) \\ subject\ \ to\ \ \mathbf{x}\in\Omega\end{aligned} maximize    f(x)subject  to  xΩ

    随机搜索方法的一个基本假设为可以从可行集 Ω \Omega Ω中进行随机采样。通常情况下,随机选择一个 x ( 0 ) ∈ Ω \mathbf{x}^{(0)}\in \Omega x(0)Ω,并在 x ( 0 ) \mathbf{x}^{(0)} x(0)附近在选择一个点作为下一个迭代点的备选。

    x \mathbf{x} x附近可选择备选点的集合为 N ( x ) N(\mathbf{x}) N(x),可以认为 N ( x ) N(\mathbf{x}) N(x) x \mathbf{x} x的一个“邻域”。

    一种简单的随机搜索算法——朴素随机搜索算法如下所示:

    1. k : = 0 k:=0 k:=0,选定初始点 x ( 0 ) ∈ Ω \mathbf{x}^{(0)} \in \Omega x(0)Ω

    2. N ( x ( k ) ) N(\mathbf{x}^{(k)}) N(x(k))随机选一个备选点 z ( k ) \mathbf{z}^{(k)} z(k)

    3. 如果 f ( z ( k ) ) &lt; f ( x ( k ) ) f(\mathbf{z}^{(k)})&lt;f(\mathbf{x}^{(k)}) f(z(k))<f(x(k)),则令 x ( k + 1 ) = z ( k ) \mathbf{x}^{(k+1)}=\mathbf{z}^{(k)} x(k+1)=z(k),否则令 x ( k + 1 ) = x ( k ) \mathbf{x}^{(k+1)}=\mathbf{x}^{(k)} x(k+1)=x(k)

    4. 如果满足停止规则,就停止迭代

    5. k : = k + 1 k:=k+1 k:=k+1,返回第2步

    3.2 模拟退火法

    朴素随机搜索算法的主要问题是有可能会在局部极小点附近“卡住”。如 N ( x ( 0 ) ) N(\mathbf{x}^{(0)}) N(x(0))已经足够小了,如果 x ( 0 ) \mathbf{x}^{(0)} x(0)为当前的局部最小点,那么算法就无法跳出 N ( x ( 0 ) ) N(\mathbf{x}^{(0)}) N(x(0))的范围,即陷入了局部最小的问题。

    一种解决途径是保证“领域 N ( x ( k ) ) N(\mathbf{x}^{(k)}) N(x(k))足够大,但一旦搜索空间大了,搜索过程也会变慢,这也导致了寻找备选点的难度加大。

    另一种方法是设置一种方法,让算法以一定概率接受比当前点要差的新点。这也是模拟退火的机制。

    模拟退火算法:

    1. k : = 0 k:=0 k:=0,选定初始点 x ( 0 ) ∈ Ω \mathbf{x}^{(0)} \in \Omega x(0)Ω

    2. N ( x ( k ) ) N(\mathbf{x}^{(k)}) N(x(k))随机选一个备选点 z ( k ) \mathbf{z}^{(k)} z(k)

    3. 设置一枚特殊的硬币,使其在一次抛投中出现正面的概率为 p ( k , f ( z ( k ) ) , f ( x ( k ) ) ) p(k,f(\mathbf{z}^{(k)}),f(\mathbf{x}^{(k)})) p(k,f(z(k)),f(x(k))),在一次抛头中,如果出现正面,则令 x ( k + 1 ) = z ( k ) \mathbf{x}^{(k+1)}=\mathbf{z}^{(k)} x(k+1)=z(k),否则 x ( k + 1 ) = x ( k ) \mathbf{x}^{(k+1)}=\mathbf{x}^{(k)} x(k+1)=x(k)

    4. 如果满足停止规则,就停止迭代

    5. k : = k + 1 k:=k+1 k:=k+1,返回第2步

    可以看出区别主要在算法第3步,这一步骤中,模拟退火法以一定概率选择选择备选点作为下一个迭代点,这一概率称为接受概率。

    常用的接受概率为:

    p ( k , f ( z ( k ) ) , f ( x ( k ) ) ) = m i n { 1 , e x p ( − ( f ( z ( k ) ) − f ( x ( k ) ) ) / T k ) } p(k,f(\mathbf{z}^{(k)}),f(\mathbf{x}^{(k)}))=min\{1,exp(-(f(\mathbf{z}^{(k)})-f(\mathbf{x}^{(k)}))/T_k)\} p(k,f(z(k)),f(x(k)))=min{1,exp((f(z(k))f(x(k)))/Tk)}

    exp表示指数函数, T k T_k Tk构成一组正数序列,称为温度进度表或冷却进度表。

    如果 f ( z ( k ) ) ≤ f ( x ( k ) ) f(\mathbf{z}^{(k)})\leq f(\mathbf{x}^{(k)}) f(z(k))f(x(k)),说明 p = 1 p=1 p=1,即始终 x ( k + 1 ) = z ( k ) \mathbf{x}^{(k+1)}=\mathbf{z}^{(k)} x(k+1)=z(k),因为备选点的函数值已经比原来的小了,所以理应作为迭代点。

    如果 f ( z ( k ) ) &gt; f ( x ( k ) ) f(\mathbf{z}^{(k)})&gt; f(\mathbf{x}^{(k)}) f(z(k))>f(x(k)),说明这个点不好,但仍有一定概率接受这个点,这个概率为:

    e x p ( − f ( z ( k ) ) − f ( x ( k ) ) T k ) exp(-\frac{f(\mathbf{z}^{(k)})-f(\mathbf{x}^{(k)})}{T_k}) exp(Tkf(z(k))f(x(k)))

    并且 f ( z ( k ) f(\mathbf{z}^{(k)} f(z(k) f ( x ( k ) ) f(\mathbf{x}^{(k)}) f(x(k))之间的差异越大,采用这个不好的点的概率就越小。类似的, T k T_k Tk越小,采用不好的点的概率也越小。

    通常的做法是令 T k T_k Tk单调递减至0,即模仿冷却的过程,直观的理解也就是随着迭代次数k的增加,算法趋于更差点的可能性就越小。

    模拟退火算法中的温度必须以可可控的方式递减,具体而言,冷却过程必须足够慢,有人给出了一个合适的冷却进度表:

    T k = γ l o g ( k + 2 ) T_k=\frac{\gamma}{log(k+2)} Tk=log(k+2)γ

    其中, γ &gt; 0 \gamma &gt;0 γ>0为常数,需要根据具体问题上设置。(需要足够大,以保证能够跳出局部最小点附近的区域)。

    4. 粒子群优化算法

    粒子群算法与上述的随机搜索算法的一个主要区别是:在一次迭代中,粒子群优化算法并不是只更新单个迭代点 x ( k ) \mathbf{x}^{(k)} x(k),而是更新一群迭代点,称为群。

    可以将群视为一个无需的群体,每个成员都在移动,旨在形成聚集,但移动方向是随机的。粒子群优化算法旨在模拟动物或昆虫的社会行为,如蜂群、鸟群和羚羊群的形成过程。

    粒子群优化算法的基本过程为,首先随机产生一组数据点,为每一个点赋予一个速度,构成一个速度向量。点本身代表粒子所在的位置,每个点以指定的速度移动。接下来针对每个数据点计算对应的目标函数值,基于计算结果再产生一组新的数据点,赋予新的速度。

    每个粒子都持续追踪其当前为止的最好位置pbest,程序也记录当前全局的最好位置gbest。

    4.1 基本的粒子群优化算法

    gbest版粒子群优化算法的简化版本,在每次迭代中,粒子的速度都朝着个体最好位置而和全局最好位置进行调整。

    符号约定:

    f : R n → R f:\mathbb{R}^n \rightarrow \mathbb{R} f:RnR为目标函数

    d d d表示群体的容量,共有d个粒子

    x i ∈ R n \mathbf{x}_i\in \mathbb{R}^n xiRn表示粒子i的位置,对应速度为 v i \mathbf{v}_i vi p i \mathbf{p}_i pi表示粒子i的pbest, g \mathbf{g} g表示gbest。

    gbest版的粒子群优化算法:

    1. k : = 0 k:=0 k:=0,选定d个初始点 x i ( 0 ) \mathbf{x}^{(0)}_i xi(0),以及对应 v i ( 0 ) \mathbf{v}^{(0)}_i vi(0) p i ( 0 ) = x i ( 0 ) \mathbf{p}^{(0)}_i=\mathbf{x}^{(0)}_i pi(0)=xi(0) g ( 0 ) = a r g   m i n x ∈ { x i ( 0 ) } f ( x ) \mathbf{g}^{(0)}=arg\ min _{x\in\{\mathbf{x}^{(0)}_i\}}f(\mathbf{x}) g(0)=arg minx{xi(0)}f(x)

    2. 对第i个粒子,随机产生两个n为向量 r i ( k ) \mathbf{r}^{(k)}_i ri(k) s i ( k ) \mathbf{s}^{(k)}_i si(k),并从(0,1)区间内抽取随机数w、c1和c2,用于计算下一次的速度向量:

      v i ( k + 1 ) = ω v i ( k ) + c 1 r i ( k ) ∘ ( p i ( k ) − x i ( 0 ) ) + c 2 s i ( k ) ( g i ( k ) − x i ( k ) ) \mathbf{v}^{(k+1)}_i=\omega \mathbf{v}^{(k)}_i+c_1\mathbf{r}^{(k)}_i\circ (\mathbf{p}^{(k)}_i-\mathbf{x}^{(0)}_i)+c_2 \mathbf{s}^{(k)}_i (\mathbf{g}^{(k)}_i-\mathbf{x}^{(k)}_i) vi(k+1)=ωvi(k)+c1ri(k)(pi(k)xi(0))+c2si(k)(gi(k)xi(k))

      x i ( k + 1 ) = x i ( k ) + v i ( k + 1 ) \mathbf{x}^{(k+1)}_i=\mathbf{x}^{(k)}_i+\mathbf{v}^{(k+1)}_i xi(k+1)=xi(k)+vi(k+1)

    3. 针对每个新的 x i ( k + 1 ) \mathbf{x}^{(k+1)}_i xi(k+1),查看它对应的函数值,判断并更新 p i ( k + 1 ) \mathbf{p}^{(k+1)}_i pi(k+1)

    4. 针对所有 x i ( k + 1 ) \mathbf{x}^{(k+1)}_i xi(k+1),查看函数值并更新 g ( k + 1 ) \mathbf{g}^{(k+1)} g(k+1)

    5. 如果满足停止条件就停止迭代,否则令k=k+1,并返回第2步。

    上面 ∘ \circ 表示矩阵按元素相乘得到新的矩阵, ω \omega ω表示惯性系数,建议取稍微小于1的值,参数c1和c2决定了粒子趋向于“好位置”的程度,表示来自“认知”和“社会”的影响因素,即粒子本身最好位置和全局最好位置的影响,建议取值 c 1 = c 2 ≈ 2 c_1=c_2\approx 2 c1=c22

    4.2 粒子群算法优化的变种

    粒子群算法提出以后,经过了不断地完善和修改。其中一种是收敛因子的粒子群优化算法,其更新速度的公式为:

    v i ( k + 1 ) = κ ( ω v i ( k ) + c 1 r i ( k ) ∘ ( p i ( k ) − x i ( 0 ) ) + c 2 s i ( k ) ( g i ( k ) − x i ( k ) ) ) \mathbf{v}^{(k+1)}_i=\kappa (\omega \mathbf{v}^{(k)}_i+c_1\mathbf{r}^{(k)}_i\circ (\mathbf{p}^{(k)}_i-\mathbf{x}^{(0)}_i)+c_2 \mathbf{s}^{(k)}_i (\mathbf{g}^{(k)}_i-\mathbf{x}^{(k)}_i)) vi(k+1)=κ(ωvi(k)+c1ri(k)(pi(k)xi(0))+c2si(k)(gi(k)xi(k)))

    其中 κ \kappa κ为收敛系数:

    κ = 2 ∣ 2 − ϕ − ϕ 2 − 4 ϕ ∣ \kappa =\frac{2}{|2-\phi -\sqrt{\phi^2-4\phi}|} κ=2ϕϕ24ϕ 2

    其中 ϕ = c 1 + c 2 , ϕ &gt; 4 \phi =c_1+c_2,\phi&gt;4 ϕ=c1+c2,ϕ>4,收敛系数的作用在于加快收敛。

    实际应用中往往希望速度能有一个上限 v m a x v_{max} vmax,之后公式里的速度更新为:

    m i n { v m a x , m a x { − v m a x , v } } min\{v_{max},max\{-v_{max},v\}\} min{vmax,max{vmax,v}}

    5. 遗传算法

    5.1 有关术语和定义

    染色体和表达模式

    遗传算法并不是直接针对约束集 Ω \Omega Ω中点进行操作,而是对这些点进行编码后进行操作。

    具体而言是将 Ω \Omega Ω映射为一个字符串的集合,这些字符串是等长的,称为染色体。

    每个染色体是从一个字符串集合中提取的,该集合称为字符表,如常用的二进制字符表{0,1},此时染色体就是二进制字符串。

    每个染色体对应一个目标函数值,称为染色体的适应度。

    字符串的长度、字符表和编码方式统称为表达模式

    一定数量的染色体构成了初始种群 P ( 0 ) P(0) P(0),之后对齐进行交叉和变异操作,在经过k次迭代之后,计算整个种群的适应度,并按照如下两个步骤构造一个新的种群 P ( k + 1 ) P(k+1) P(k+1)

    选择和进化步骤

    选择——将表现好的染色体选择出来放到另一个地方

    • 轮盘赌模式
    • 锦标赛模式

    轮盘赌模式

    选择的过程是将 P ( k ) P(k) P(k)种群中生成 M ( k ) M(k) M(k)种群,两个种群中的染色体数量相同,都为N,这意味表现好的染色体会被重复选入M(k),每个染色体被选择的概率为:

    f ( x i ( k ) ) ∑ f ( x i ( k ) ) \frac{f(\mathbf{x}^{(k)}_i)}{\sum f(\mathbf{x}^{(k)}_i)} f(xi(k))f(xi(k))

    即个体的适应度与种群的适应度间的比值。

    锦标赛模式:

    从P(k)中随机选择两个染色体,比较他们的适应度,将表现好的放入M(k)中,不断进行这种操作,直到M(k)中的染色体数量为N。

    进化——对M(k)中的染色体进行交叉和变异

    交叉:从配对池M(k)中选择“父代”染色体,选择一个交叉点,交叉后生成“子代”,之后利用子代的染色体替代配对池中的染色体。

    变异:从配对池中抽取染色体,并以一定概率随机改变其中的某个元素,产生变异。

    5.2 遗产算法步骤

    1. k : = 0 k:=0 k:=0,产生一个初始种群P(0)
    2. 评估P(k),即计算种群中每个个体的适应度
    3. 如果满足停止条件就停止
    4. 从P(k)中选择M(k)
    5. 进化M(k),构成新的种群P(k+1)
    6. 令k=k+1,返回到第2步

    流程图如下所示:

    [外链图片转存失败(img-rFmtOdh4-1566486265977)(assets/1564663134090.png)]

    在遗传算法的迭代过程中,持续追踪当前为止最好的染色体,即适应度最高的染色体。在一次迭代后,当前为止最好的染色体作为最优解的备选。实际上,甚至可以将其复制到新一代种群中。这是精英主义者的做法,这种精英主义的策略容易导致种群被“超级染色体”主导。但是,实际应用经验表明,精英主义的策略很多时候可以提高算法的性能。

    遗传算法和其它优化算法有如下不同:

    第一,不需要计算目标函数的导数(全局搜索的其他方法也有这个性质)。

    第二,在每次迭代中,采用的是随机操作(与其他随机搜索方法是一致的)。

    第三,每次迭代是利用一组点而不是一个点开展搜索(与粒子群优化算法相似)。

    第四,对约束集进行编码,而不是直接在约束集本身上开展搜索。

    展开全文
  • C语言全局数组与局部数组

    万次阅读 2012-12-09 01:00:39
    今天同学遇到一个在C语言中全局数组和局部数组的问题,了许久,我也没有第一时间看出问题,现在把问题梳理一下,并给出解决方案。 问题描述: 在全局声明的数组与在局部声明的数组有着不同的效果。 首先来看一...
  • 下面我们先描述一下N+1问题,再讨论全局设定的延迟加载。 1、N+1问题 在做完前面三篇入门的例子后,让我们运行一下以下: package com.ykzhen2014.csdn.main; import org.apache.ibatis.session.SqlSession; ...
  • Android 全局异常错误或崩溃捕捉

    千次阅读 2015-10-18 09:52:00
    当出现崩溃,软件不会闪退,会出现弹出一个对话框,异常错误信息会自动保存在sdcrash这个文件夹下。后续需要还可以发送到服务器的。看效果图。 1、实现效果图 2、全局异常捕捉类CrashHandler package ...
  • 设置源码解析--Uim/Sim锁定

    千次阅读 2014-01-22 20:54:03
    android 设置应用源码解析  功能入口:设置--安全--Sim锁定
  • nameUUIDFromBytes(byte[] n)会根据n产生唯一的uuid。只要有用户的唯一性信息。就能保证此用户的uuid的唯一性。例如(身份证号等) 我们更愿意使用自定义唯一编号,再使用该编号生成唯一的UUID。 我们通过一个...
  • 多队列网卡及RPS/RFS/XPS设置

    千次阅读 2019-10-30 22:19:24
    因此我们需要设置这两个表中记录的entry,对于全局socket流表(rps_sock_flow_table),该配置接口是 /proc/sys/net/core/rps_sock_flow_entries 而设备流表(rps_dev_flow_table)则通过以下接口设置, /sys/...
  • webstorm怎么使用全局搜索

    万次阅读 2018-02-24 14:45:50
    webstorm怎么使用全局搜索ctrl+shift+N通过文件名快速查找工程内的文件(必记)ctrl+shift+alt+N通过一个字符快速查找位置(必记)ctrl+F在文件内快速查找代码F3查找下一个shift+F3查找上一个ctrl+R文件内代码替换ctrl+...
  • SmallPT代码分析2.1 代码块12.2 代码块22.2.1 主函数第1步: 设置呈像平面2.2.2 主函数第2步: 设置相机位置2.2.3 主函数第3步: 创建图像2.2.4 如何计算radiance?2.3 shading 着色2.3.1 diffuse reflection 漫反射...
  • Matlab数学建模(六):全局优化

    千次阅读 2018-11-25 21:32:53
    (1)了解全局优化算法在数学建模中的重要地位。 (2)以著名的旅行商问题为例,掌握如何使用遗传算法。 (3)以经典的Peaks 问题为例,掌握如何使用模拟退火算法。 二、实例演练 1、全局优化算法在数学建模中的...
  • 今天同学遇到一个在C语言中全局数组和局部数组的问题,了许久,我也没有第一时间看出问题,现在把问题梳理一下,并给出解决方案。 问题描述: 在全局声明的数组与在局部声明的数组有着不同的效果。 首先来看一个...
  • 项目属性设置:项目属性设置中的属性是全局属性,适用于该项目下的所有对象。   项目属性包含两个选项,分别是 Info (信息)选项和 Build Settings 选项。 Info 选项主要有三个分组:  ...
  • UUID全局唯一标识符

    千次阅读 2017-11-14 22:45:58
    对基于时间的UUID版本,时间序列用于避免因时间向后设置或节点值改变可能造成的UUID重复,对基于名称或随机数的版本同样有用:目的都是为了防止UUID重复。如果前一时钟序列已知,通过自增实现时钟序列值的改变;否则...
  • pyqt全局鼠标事件/钩子

    千次阅读 2017-12-11 22:00:33
    之前我们用RegisterHotKey实现了全局热键。今天我们来学习一下全局钩子的知识。来结束我这几天的研究。笔者用的是python3.6首先我们要明白一些关键的部分: 钩子分为线程钩子和系统钩子两种。 线程钩子是局部的,...
  • Java全局变量与局部变量 1)Java变量类型 Java语言支持的变量类型有:全局变量和局部变量。全局变量又分为类变量、实例变量。 (1)类变量:也称静态变量,也就是在实例变量前加了static 的变量。静态变量必定义...
  • 全局优化算法:模拟退火算法

    千次阅读 2017-02-28 11:03:50
    因此,为了保证算法收敛到全局最小点,有时需要在全局极小点附近选择初始点。此外,这些方法需要计算目标函数。全局优化算法又称现代启发式算法,是一种具有全局优化性能、通用性强且适合于并行处理的算法。 这种...
  • 有些出口可以获取键盘消息,有些不能获取键盘消息,这是全局钩子,我是菜鸟,求大神帮助啊!!! 补充一下,程序运行时,切换到其他程序,有的可以获取键盘消息,printf有响应;有的没有任何响应,比如切换到网页...
  • Android开发之全局异常捕获

    万次阅读 2017-08-22 14:53:28
    Android开发之全局异常捕获今晨谷歌正式发布Android 8.0,新版本的Android O系统对API做出了各种变更,其中大部分会影响到很多应用,其中包括记录未捕获的异常. 如果某个应用安装的Thread.UncaughtExceptionHandler...
  • MPI——进程之间的全局通信

    千次阅读 2019-09-02 20:51:34
    进程之间的全局通信四种基本的MPI原语:广播、收集、归约和全交换阻塞与非阻塞和同步与异步通信阻塞通信产生的死锁并发性:局部计算可以与通信重叠执行单向与双向通信MPI的全局计算归约操作并行前缀采用通信器定义...
  • Android全局异常捕获机制

    万次阅读 2017-06-15 21:26:45
    为我们的项目提供一个异常捕获跟踪处理机制,我认为应包含捕获异常、写入异常数据到SD中、定时上传异常数据给服务端、服务端统计分析异常、最终目标为解决异常从而提高代码的健壮性。 下面提供一个客户端这边的...
  • GPU之间不通过CPU,直接将数据从一块GPU上的数据传输到另一个GPU上。 CPU主机端处理器可以通过以下三种方式对GPU上的内存进行访问: 【1】显式地阻塞传输 【2】显式地非阻塞传输 【3】隐式的使用零内存复制...
  • adb shell配置全局变量以及常用命令

    千次阅读 2016-04-01 11:31:44
    adb配置全局变量以及常用命令
  • 开发Android项目时,经常会遇到程序崩溃的情况,这时我们可以在logcat中查看崩溃日志,但有时错误的堆栈信息并没有显示出来... * 全局异常捕获 * Created by ljw on 2017/7/3. */ public class CrashHandler impl...
  • 解析全局光照Global Illumination Explained 前言:Global Illumination全局光照技术是实时渲染的必然发展方向。我参考了一些研究成果,琢磨了一下,让更多的人可以理解这项“古老”的技术。 Front Line 虽然说...
  • VxWorks全局变量的保护

    千次阅读 2007-12-04 20:34:00
    VxWorks全局变量的保护VxWorks操作系统是一个应用比较多的实时多任务操作系统。它提供并支持多任务调度机制,用户可以将自己对事件的控制通过不同任务的协调而完成。各个任务之间通过全局变量、信号量、管道等方式...
  • Android全局捕获crash并保存日志到本地
  • 基于全局信息的人脸识别总结

    千次阅读 热门讨论 2007-10-29 12:19:00
    黄叶权 整理于 2007年6月一、 课题名称基于全局信息的人脸识别算法研究二、 课题的提出在当今社会中,身份确认具有十分重要的价值。随着网络技术的发展,信息安全也显示出了前所未有的重要性。在经济、政府、安防和...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 61,519
精华内容 24,607
关键字:

n卡全局设置