CMinpack使用介紹

来源:https://www.cnblogs.com/bemfoo/archive/2019/07/17/11203993.html
-Advertisement-
Play Games

github: 主頁: 使用手冊: LMDIF使用說明 官方英文介紹: 包括函數名 ,` lmdif1_` 最小化非線性函數平方和 函數概要 詳細描述 的目的是最小化m個n元非線性方程的平方和,使用的方法是LM演算法的改進。用戶需要提供計算方程的子程式。Jacobian矩陣會通過一個前向差分(forw ...


github: https://github.com/devernay/cminpack
主頁: http://devernay.github.io/cminpack/
使用手冊: http://devernay.github.io/cminpack/man.html

CMinpack配置

從github中clone下來源文件,進入目錄後新建build,使用cmake對上一層目錄內容進行編譯configure->generate。

命令行不熟練可以使用cmake-gui指令,需要選中examples選項才會對樣例進行編譯。

完成後進入build/examples目錄,執行make命令,可以看到已經生成可執行文件,運行其中任意程式進行測試。

再進入到build/cmake目錄,執行make命令和make install命令,將cminpack.pc安裝到指定目錄(我的電腦上安裝到了/usr/local/lib64/pkgconfig),最後將這個目錄通過/etc/profile添加到pkg的路徑當中(別忘了source運行一下)。
在命令行中輸入pkg-config opencv –libs –cflags ,如果能夠顯示路徑則成功。
[NOTE] 我對pkg-config的使用並不是很瞭解,是模仿著opencv進行配置的。

CMake相關詳解

[NOTE] 因此自己對CMake使用還很不熟練,因此找機會對CMakeList.txt進行學習。

${CMINPACK_SOURCE_DIR}/CMakeList.txt

# 因為Markdown沒有支持CMakeList.txt的高亮,因此用Makefile的高亮將就一下。

# The name of our project is "CMINPACK". CMakeLists files in this project can
# refer to the root source directory of the project as ${CMINPACK_SOURCE_DIR} and
# to the root binary directory of the project as ${CMINPACK_BINARY_DIR}.
# CMINPACK_SOURCE_DIR: CMinpack源代碼的根目錄
# CMINPACK_BINARY_DIR: CMinpack二進位文件的根目錄

# 要求的最小CMake版本號
cmake_minimum_required (VERSION 2.6)

# 項目名稱:CMINPACK
project (CMINPACK)

# PROJECT_NAME: CMINPACK
# PROJECT_NAME_LOWER: cminpack
string(TOLOWER ${PROJECT_NAME} PROJECT_NAME_LOWER)

# include其他CMake命令
# 在cminpack_utils.cmake這個文件中定義了GET_OS_INFO和DISSECT_VERSION兩個巨集指令,後面進行詳細介紹。
include(${PROJECT_SOURCE_DIR}/cmake/cminpack_utils.cmake)
# Set version and OS-specific settings
# CACHE: 緩存到本地文件
set(CMINPACK_VERSION 1.3.6 CACHE STRING "CMinpack version")
set(CMINPACK_SOVERSION 1 CACHE STRING "CMinpack API version")
# 在cminpack_utils.cmake中定義的兩個巨集
DISSECT_VERSION()
GET_OS_INFO()

# Add an "uninstall" target
# CONFIGURE_FILE: 讓普通文件也能使用CMake中的變數
# 輸入文件: uninstall_target.cmake.in
# 輸出文件: uninstall_target.cmake
# IMMEDIATE: 暫時沒找到意思
# @ONLY: 限制只替換被@VAR@引用的變數(${VAR}格式的變數不會被替換)
CONFIGURE_FILE ("${PROJECT_SOURCE_DIR}/cmake/uninstall_target.cmake.in" "${PROJECT_BINARY_DIR}/uninstall_target.cmake" IMMEDIATE @ONLY)

# ADD_CUSTOM_TARGET: 增加一個沒有輸出的目標,使得它總是被構建
# CMAKE_COMMAND: 指向CMake可執行文件的完整路徑
ADD_CUSTOM_TARGET (uninstall "${CMAKE_COMMAND}" -P "${PROJECT_BINARY_DIR}/uninstall_target.cmake")

# 需要註意,ctest期望在build目錄下找到測試文件。
enable_testing()

if (OS_LINUX OR ${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
  option (USE_FPIC "Use the -fPIC compiler flag." ON)
else (OS_LINUX)
  option (USE_FPIC "Use the -fPIC compiler flag." OFF)
endif (OS_LINUX)

# 生成SHARED庫的選項
option (BUILD_SHARED_LIBS "Build shared libraries instead of static." OFF)
if (BUILD_SHARED_LIBS)
  message (STATUS "Building shared libraries.")
else ()
  message (STATUS "Building static libraries.")
  set(CMAKE_RELEASE_POSTFIX _s)
  set(CMAKE_RELWITHDEBINFO_POSTFIX _s)
  set(CMAKE_DEBUG_POSTFIX _s)
  set(CMAKE_MINSIZEREL_POSTFIX _s)
  if(WIN32)
    add_definitions(-DCMINPACK_NO_DLL)
  endif(WIN32)
endif ()

option(USE_BLAS "Compile cminpack using a blas library if possible" ON)

#set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/../build)

# 添加頭文件目錄
if(NOT "${CMAKE_PREFIX_PATH}" STREQUAL "")
  include_directories(${CMAKE_PREFIX_PATH}/include)
endif()

# cminpack_srcs: 源代碼文件
set (cminpack_srcs
  cminpack.h cminpackP.h
  chkder.c  enorm.c   hybrd1.c  hybrj.c   lmdif1.c  lmstr1.c  qrfac.c   r1updt.c
  dogleg.c  fdjac1.c  hybrd.c   lmder1.c  lmdif.c   lmstr.c   qrsolv.c  rwupdt.c
  dpmpar.c  fdjac2.c  hybrj1.c  lmder.c   lmpar.c   qform.c   r1mpyq.c  covar.c covar1.c
  minpack.h
  chkder_.c enorm_.c  hybrd1_.c hybrj_.c  lmdif1_.c lmstr1_.c qrfac_.c  r1updt_.c
  dogleg_.c fdjac1_.c hybrd_.c  lmder1_.c lmdif_.c  lmstr_.c  qrsolv_.c rwupdt_.c
  dpmpar_.c fdjac2_.c hybrj1_.c lmder_.c  lmpar_.c  qform_.c  r1mpyq_.c covar_.c
  )
# cminpack_hdrs: 頭文件
set (cminpack_hdrs
    cminpack.h minpack.h)

# 添加一個名為cminpack的庫
add_library (cminpack ${cminpack_srcs})

if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
  TARGET_LINK_LIBRARIES(cminpack m)
endif()

# Link with a BLAS library if requested
if (USE_BLAS)
  if (NOT BUILD_SHARED_LIBS)
    set(BLA_STATIC True)
  endif()
  find_package(BLAS)
  if (BLAS_FOUND)
    target_link_libraries(cminpack PUBLIC ${BLAS_LIBRARIES})
    set_target_properties(cminpack PROPERTIES LINK_FLAGS "${BLAS_LINKER_FLAGS}")
    target_compile_definitions(cminpack PUBLIC -DUSE_CBLAS)
  endif()
endif()

# install: 為工程生成安裝規則
# TARGETS版本的install命令
install (TARGETS cminpack
   # 模塊庫
   LIBRARY DESTINATION ${CMINPACK_LIB_INSTALL_DIR} COMPONENT library
   # 靜態鏈接的庫文件
   ARCHIVE DESTINATION ${CMINPACK_LIB_INSTALL_DIR} COMPONENT library
   # 動態庫
   RUNTIME DESTINATION bin COMPONENT library)
# FILES版本的install命令
# 以相對路徑方式給出的文件名是相對當前源代碼路徑而言的,預設具有OWNER_WRITE, OWNER_READ, GROUP_READ和WORLD_READ許可權
install (FILES ${cminpack_hdrs} DESTINATION ${CMINPACK_INCLUDE_INSTALL_DIR}
    COMPONENT cminpack_hdrs)

if (USE_FPIC AND NOT BUILD_SHARED_LIBS)
  set_target_properties (cminpack PROPERTIES COMPILE_FLAGS -fPIC)
endif ()

set_target_properties(cminpack PROPERTIES VERSION ${CMINPACK_VERSION} SOVERSION ${CMINPACK_SOVERSION})

# add_subdirectory: 添加子項目
add_subdirectory (cmake)
add_subdirectory (examples)

${CMINPACK_SOURCE_DIR}/cmake/cminpack_utils.cmake

# 獲取系統信息,設置安裝位置
macro(GET_OS_INFO)
    # string(REGEX MATCH 正則表達 輸出變數 )
    string(REGEX MATCH "Linux" OS_LINUX ${CMAKE_SYSTEM_NAME})
    string(REGEX MATCH "BSD" OS_BSD ${CMAKE_SYSTEM_NAME})
    if(WIN32)
        set(OS_WIN TRUE)
    endif(WIN32)

    if(NOT DEFINED CMINPACK_LIB_INSTALL_DIR)
    set(CMINPACK_LIB_INSTALL_DIR "lib")
    if(OS_LINUX)
        if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
            set(CMINPACK_LIB_INSTALL_DIR "lib64")
        else(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
            set(CMINPACK_LIB_INSTALL_DIR "lib")
        endif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
        message (STATUS "Operating system is Linux")
    elseif(OS_BSD)
        message (STATUS "Operating system is BSD")
    elseif(OS_WIN)
        message (STATUS "Operating system is Windows")
    else(OS_LINUX)
        message (STATUS "Operating system is generic Unix")
    endif(OS_LINUX)
    endif(NOT DEFINED CMINPACK_LIB_INSTALL_DIR)
    # 比如/usr/local/include/cminpack-1
    set(CMINPACK_INCLUDE_INSTALL_DIR "include/${PROJECT_NAME_LOWER}-${CMINPACK_MAJOR_VERSION}")
endmacro(GET_OS_INFO)

# 解剖CMinpack版本號
macro(DISSECT_VERSION)
    # Find version components
    string(REGEX REPLACE "^([0-9]+).*" "\\1"
        CMINPACK_MAJOR_VERSION "${CMINPACK_VERSION}")
    string(REGEX REPLACE "^[0-9]+\\.([0-9]+).*" "\\1"
        CMINPACK_MINOR_VERSION "${CMINPACK_VERSION}")
    string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1"
        CMINPACK_REVISION_VERSION ${CMINPACK_VERSION})
    string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.[0-9]+(.*)" "\\1"
        CMINPACK_CANDIDATE_VERSION ${CMINPACK_VERSION})
endmacro(DISSECT_VERSION)

${CMINPACK_SOURCE_DIR}/examples/CMakeLists.txt

# 可選項
# option (選項名 "選項註釋" 預設內容)
option (BUILD_EXAMPLES "Build the examples and tests." ON)
option (BUILD_EXAMPLES_FORTRAN "Build the FORTRAN examples and tests." OFF)

if (BUILD_EXAMPLES)
  # Make sure the compiler can find include files from our cminpack library.
  include_directories (${CMINPACK_SOURCE_DIR})

  # Make sure the linker can find the cminpack library once it is built.
  link_directories (${CMINPACK_BINARY_DIR})

  # 設置變數內容
  # set(變數 內容)
  set (FPGM tchkder thybrd thybrd1 thybrj thybrj1 tlmder tlmder1 tlmdif tlmdif1 tlmstr tlmstr1)
  set (CPGM ${FPGM} tfdjac2)

  # cmpfile: 用於一行行地比較兩個文件的異同
  # cmpfiles could be used by runtest.cmake... for now it's unused
  # add_executable(可執行文件名稱 源文件)
  add_executable (cmpfiles cmpfiles.c)

  # inspired by http://www.netlib.org/clapack/clapack-3.2.1-CMAKE/TESTING/CMakeLists.txt
  # except that here we have to compare the output to a reference
  # 測試部分跳過不看
  macro(add_minpack_test testname reference)
    set(TEST_OUTPUT "${CMINPACK_BINARY_DIR}/examples/${testname}.out")
    set(TEST_REFERENCE "${CMINPACK_SOURCE_DIR}/examples/ref/${reference}.ref")
    get_target_property(TEST_LOC ${testname} LOCATION)
    add_test(${testname} "${CMAKE_COMMAND}"
      -DTEST=${TEST_LOC}
      -DOUTPUT=${TEST_OUTPUT} 
      -DREFERENCE=${TEST_REFERENCE} 
      -DINTDIR=${CMAKE_CFG_INTDIR}
      -P "${CMINPACK_SOURCE_DIR}/examples/runtest.cmake")
  endmacro(add_minpack_test)

  # 遍歷處理每一個目標文件
  foreach (source ${CPGM})
    add_executable (${source}_ ${source}_.c)
    target_link_libraries (${source}_ cminpack)
    if (OS_LINUX)
      target_link_libraries (${source}_ m)
    endif (OS_LINUX)
    add_minpack_test(${source}_ ${source}c)
    add_executable (${source}c ${source}c.c)
    target_link_libraries (${source}c cminpack)
    if (OS_LINUX)
      target_link_libraries (${source}c m)
    endif (OS_LINUX)
    add_minpack_test(${source}c ${source}c)
  endforeach(source)
endif (BUILD_EXAMPLES)

# FORTRAN部分跳過不看

第一個CMinpack程式

根據我們閱讀給出的測試樣例的CMake相關文件,我們可以開始動手寫自己的第一個CMinpack程式。
新建目錄,目錄下放著我們要運行的使用了CMinpack的程式my-cminpack-demo.c。
開始編寫CMakeLists.txt文件,首先提取出我們需要的內容:

project(my-cminpack-demo)
cmake_minimum_required (VERSION 2.6)

include_directories (${CMINPACK_SOURCE_DIR})
link_directories (${CMINPACK_BINARY_DIR})

add_executable (my-cminpack-demo my-cminpack-demo.c)
target_link_libraries (my-cminpack-demo cminpack)
if (OS_LINUX)
  target_link_libraries (my-cminpack-demo m)
endif (OS_LINUX)

然後新建build目錄,在build目錄下運行cmake ..
發現會跳出找不到sqrt函數的錯誤,這個我們能夠一下子聯想到是Linux系統下沒有連接到m庫文件的原因。雖然我不知道這個判斷為什麼無法執行,但是我們已知在Linux環境下,把它去掉。
得到最終的CMakeLists.txt:

project(my-cminpack-demo)
cmake_minimum_required (VERSION 2.6)

include_directories (${CMINPACK_SOURCE_DIR})
link_directories (${CMINPACK_BINARY_DIR})

add_executable (my-cminpack-demo my-cminpack-demo.c)
target_link_libraries (my-cminpack-demo cminpack)
target_link_libraries (my-cminpack-demo m)

雖然我們make得到可執行文件,運行後查看結果(圖中我使用了tlmdif_.c作為測試)

LMDIF使用說明

官方英文介紹:http://devernay.github.io/cminpack/lmdif_.html

包括函數名

lmdif,lmdif1_ - 最小化非線性函數平方和

函數概要

include <minpack.h>
void lmdif1_(void (*fcn)(int *m, int *n, double *x, double *fvec, int *iflag),
    int *m, int *n, double *x, double *fvec,
    double *tol, int *info, int *iwa, double *wa, int *lwa);


void lmdif_(void (*fcn)(int *m, int *n, double *x,  double *fvec, int *iflag),
            int *m, int *n, double *x, double *fvec,
            double *ftol, double *xtol, double *gtol, int *maxfev, double *epsfcn, double *diag, 
            int *mode, double *factor, int *nprint, int *info, int *nfev, double *fjac,
            int *ldfjac, int *ipvt, double *qtf,
            double *wa1, double *wa2, double *wa3, double *wa4 );

詳細描述

lmdif_的目的是最小化m個n元非線性方程的平方和,使用的方法是LM演算法的改進。用戶需要提供計算方程的子程式。Jacobian矩陣會通過一個前向差分(forward-difference)近似計算得到。
lmdif1_是相同的目的,但是調用方法更簡單一些。

語言備註

這些函數是通過FORTRAN寫的,如果從C調用,需要記住以下幾點:

  • 名稱重編:
    • 2.95/3.0版本的g77下,所有函數以下劃線結尾,後續版本可能會更改;
  • 使用g77編譯:
    • 即使你的程式全部用C語言寫成,你也需要使用gcc進行鏈接,因為這樣它會自動導入FORTRAN庫。只使用g77進行編譯是最方便的(它處理C語言也是OK的);
  • 通過引用調用:
    • 所有函數參數都是指針;
  • 列優先數組:
    • z( i , j ) = z[ ( i - 1 ) + ( j - 1 ) * n
    • fcn是用戶提供用於計算函數的子程式。在C語言當中fcn需要如下定義:
    void fcn(int m, int n, double *x, double *fvec, int *iflag) {
      /* 計算函數在x點的值,通過fvec返回。*/
    }
    iflag的值不能被fcn所修改,除非用戶想要終止lmdif/lmdif1_。在這個例子中iflag設置為負整數。

lmdif_和lmdif1_的共同參數

m:函數個數;
n:變數個數(n<=m)
x:長度為n的數組,設置為初始的估計解向量。輸出的時候x內容為最終估計的解向量。
fvec:輸出長度為m的數組,內容為最終輸出x計算得到的函數解。

lmdif1_的參數

tol:作為輸入,非負數。用於函數終止的條件判斷:

  • 平方和小於tol;
  • x之間的相對誤差小於tol;

info:作為輸出。如果用戶終止了函數的執行,info將被設置為iflag的值(負數)(詳細見fcn的描述),否則,info的值如下幾種情況:

  • 0:輸入參數不合適;
  • 1:平方和的相對誤差小於tol;
  • 2:x之間的相對誤差小於tol;
  • 3:1/2兩種情況同時符合;
  • 4: fvec is orthogonal to the columns of the Jacobian to machine precision(這個情況是什麼暫時不是很清楚)
  • 5:調用fcn的次數達到了200*(n+1)次;
  • 6:tol設置過小,平方和無法達到那麼小;
  • 7:tol設置過小,x的近似解無法優化到誤差達到那麼小。

iwa:長度n的工作數組;
wa:長度lwa的工作數組;
lwa:作為輸入,整數,不能小於mn+5n+m;
[NOTE] 這三個輸入我也不知道作用,從樣例來看不需要初始化。

lmdif_的參數

暫時不用這部分,跳過。

官方樣例解讀

源碼: https://github.com/devernay/cminpack/blob/d1f5f5a273862ca1bbcf58394e4ac060d9e22c76/examples/tlmdif1_.c

/*     lmdif1 例子. */
#include <stdio.h>
#include <math.h>
#include <assert.h>
#include <minpack.h>
#define real __minpack_real__

// 用戶自定義的函數f()
// real -> __cminpack_real__ -> 浮點數(double)
void fcn(const int *m, const int *n, const real *x, real *fvec, int *iflag);

int main()
{
  int j, m, n, info, lwa, iwa[3], one=1;
  real tol, fnorm, x[3], fvec[15], wa[75];

  // 函數個數15; 變數數3
  m = 15;
  n = 3;

  // 初始位置做粗略估計
  // 1.e0 = 1.0e0 = 1.0
  x[0] = 1.e0;
  x[1] = 1.e0;
  x[2] = 1.e0;

  // 為什麼要設置75?
  lwa = 75;

  /* set tol to the square root of the machine precision.  unless high
     precision solutions are required, this is the recommended
     setting. */
  // (建議列印一下看值是多少)

  tol = sqrt(__minpack_func__(dpmpar)(&one));

  // 需要註意指針
  __minpack_func__(lmdif1)(&fcn, &m, &n, x, fvec, &tol, &info, iwa, wa, &lwa);

  // 最終的2範數(即平方和開根號)
  fnorm = __minpack_func__(enorm)(&m, fvec);
  printf("      final l2 norm of the residuals%15.7g\n\n", (double)fnorm);
  printf("      exit parameter                %10i\n\n", info);
  printf("      final approximate solution\n");
  for (j=1; j<=n; j++) {
    printf("%s%15.7g", j%3==1?"\n ":"", (double)x[j-1]);
  }
  printf("\n");
  return 0;
}

//        The problem is to determine the values of x(1), x(2), and x(3)
//        which provide the best fit (in the least squares sense) of
//              x(1) + u(i)/(v(i)*x(2) + w(i)*x(3)),  i = 1, 15
//        to the data
//              y = (0.14,0.18,0.22,0.25,0.29,0.32,0.35,0.39,
//                   0.37,0.58,0.73,0.96,1.34,2.10,4.39),
//        where u(i) = i, v(i) = 16 - i, and w(i) = min(u(i),v(i)).  The
//        i-th component of FVEC is thus defined by
//              y(i) - (x(1) + u(i)/(v(i)*x(2) + w(i)*x(3))).

void fcn(const int *m, const int *n, const real *x, real *fvec, int *iflag)
{
  /* function fcn for lmdif1 example */

  int i;
  real tmp1,tmp2,tmp3;

  // 實際的y值
  real y[15]={1.4e-1,1.8e-1,2.2e-1,2.5e-1,2.9e-1,3.2e-1,3.5e-1,3.9e-1,
              3.7e-1,5.8e-1,7.3e-1,9.6e-1,1.34e0,2.1e0,4.39e0};
  assert(*m == 15 && *n == 3);


  if (*iflag == 0) {
    /*      insert print statements here when nprint is positive. */
    /* if the nprint parameter to lmder is positive, the function is
       called every nprint iterations with iflag=0, so that the
       function may perform special operations, such as printing
       residuals. */
    // 這段沒有很看懂,在??情況下列印信息
    return;
  }

  /* compute residuals */

  for (i=0; i<15; i++) {
    tmp1 = i+1;
    tmp2 = 15 - i;
    tmp3 = tmp1;
    if (i >= 8) {
      tmp3 = tmp2;
    }
    fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));
  }
}

[NOTE] 其他內容有待更新


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、單例模式 1、概念圖解 單例設計模式定義:確保這個類只有一個實例,並且自動的實例化向系統提供這個對象。 2、樣例代碼 Singleton稱為單例類,構造函數使用private修飾,確保系統中只能產生一個實例,並且自動生成的。上面代碼也就是所謂的懶漢式載入:只有到使用該對象的時候才來創建,意思餓了 ...
  • 測試結果 擴展: 可以更改"%Y-%m-d %H:%M:%S",得到任何你想要的格式 如201907170730,對應“%Y%m%d%H%M”等等,看自己需要 【END】 ...
  • Django基礎二之URL路由系統 MVC和MTV框架 MVC Web伺服器開發領域里著名的MVC模式,所謂MVC就是把Web應用分為模型(M),控制器(C)和視圖(V)三層,他們之間以一種插件式的、松耦合的方式連接在一起,模型負責業務對象與資料庫的映射(ORM),視圖負責與用戶的交互(頁面),控制 ...
  • 閱讀目錄 一、三大編程範式 編程範式即編程的方法論,標識一種編程風格: 大家學習了基本的python語法後,大家可以寫python代碼了,然後每個人寫代碼的風格不同,這些不同的風格就代表了不同的流派; 如果把python的基本語法比作武術的基本功,那麼不同的編程風格就好比不同的武林門派。 雖然大家風 ...
  • 前面介紹瞭如何使用畫筆工具Graphics繪製各種圖案,然而Graphics並不完美,它的遺憾之處包括但不限於:1、不能設置背景顏色;2、雖然提供了平移功能,卻未提供旋轉功能與縮放功能;3、只能在控制項上作畫,無法將整幅畫保存為圖片;有鑒於此,AWT提供了Graphics的升級版名叫Graphics2 ...
  • 11-3 雇員:編寫一個名為Employee的類,其方法__init__() 接受名、姓和年薪,並將它們都存儲在屬性中。編寫一個名為give_raise()的方法,它預設將年薪增加5000美元,但也能夠接受其他的年薪增加量。 為Employee編寫一個測試用例,其包含兩個測試方法:test_give ...
  • a=1 聲明變數 a 變數的名字 = 賦值 1 值 變數定義的規則: 1. 變數由數字,字母,下劃線組成(不能加空格): a a_1 a1 2. 不能以數字開頭 3. 不能使用python中的關鍵字(寫的時候變藍了) 4. 不能使用中文和拼音 5. 區分大小寫 6. 變數名要具有描述性 7. 推薦寫 ...
  • SpringBoot快速入門--環境搭建 1、創建web工程 1.1 創建新的工程。 1.2 選擇maven工程,點擊下一步。 1.3 填寫groupid(maven的項目名稱)和artifactid(項目模塊)。點擊下一步 1.4 確認自己的項目路徑後,點擊finish。 2、添加springbo ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...