---
# System prepended metadata

title: Python和CUDA(C++)量子退火和伊辛二次算法模型 | 亞圖跨際

---

# Python和CUDA(C++)量子退火和伊辛二次算法模型
1. 简化量子退火或离散优化算法处理，使用张量网络模拟和动态系统方法及神经网络逼近。
2. 实现并行退火算法和CUDA支持下穷举搜索法。
3. 使用大都会算法模拟二维自旋玻璃伊辛模型并测量磁化率、比热容和能量。
4. 对比其他组合优化解方法，使用英伟达A100 GPU测试。
## :maple_leaf:自旋玻璃退火算法
```mermaid
%%{init:{'gitGraph':{'mainBranchName':'自旋玻璃'},'themeVariables':{'commitLabelBackground': 'None','commitLabelFontSize':'20px'}}}%%
  gitGraph
   commit id:"数学"
   commit id:"凝聚态物理学"
   branch "Python和MATLAB自旋玻璃投资组合神经网络广义方程"
   branch "Python和C++及MATLAB低温磁态机器学习模型"
   checkout "Python和MATLAB自旋玻璃投资组合神经网络广义方程"
   commit id:"模拟"
   branch "Python和CUDA(C++)并行退火和伊辛二次算法模型(量子计算)"
   branch "CUDA(C)磁态蒙特卡洛和传输矩阵多GPU并行计算分析"
   commit id:"蒙特卡洛"
   commit id:"传输矩阵"
   commit id:"多GPU"
   commit id:"多CUDA线程"
   commit id:"多任务"
   checkout "Python和CUDA(C++)并行退火和伊辛二次算法模型(量子计算)"
   commit id:"量子退火"
   commit id:"张量网络"
   commit id:"磁化率"
   commit id:"比热容"
   commit id:"能量"
   checkout "Python和C++及MATLAB低温磁态机器学习模型"
   commit id:"热图"
   commit id:"量子近似优化"
   commit id:"小规模磁态训练"
   commit id:"贪婪算法"
   commit id:"模拟退火算法"
   commit id:"并行回火算法"
   commit id:"图神经网络"
   commit id:"机器学习"
   checkout "自旋玻璃"
   merge "Python和MATLAB自旋玻璃投资组合神经网络广义方程"
   merge "Python和C++及MATLAB低温磁态机器学习模型"
   merge "CUDA(C)磁态蒙特卡洛和传输矩阵多GPU并行计算分析"
   merge "Python和CUDA(C++)并行退火和伊辛二次算法模型(量子计算)"
```
## :cookie:语言内容分比

```mermaid
pie title 语言分比
 "Python":90
 "CUDA":80
 "C/C++":40
 "Julia":30
```

```mermaid
pie title 内容分比
 "算法模型":90
 "物理学、量子计算、伊辛模型":80
 "数学、相关系数、张量、矩阵":30
```

## :grapes:Python伊辛模型

伊辛模型（或伦茨-伊辛模型）以物理学家恩斯特·伊辛和威廉·伦茨的名字命名，是统计力学中铁磁性的数学模型。该模型由离散变量组成，这些变量表示原子“自旋”的磁偶极矩，可以处于两种状态之一（1 或 −1）。自旋排列成一个图形，通常是晶格（其中局部结构在所有方向上周期性重复），允许每个自旋与其邻居相互作用。相邻的一致自旋的能量低于不一致的自旋；系统趋向于最低能量，但热量会干扰这种趋势，从而产生不同结构相的可能性。该模型允许将相变识别为现实的简化模型。二维方晶格伊辛模型是显示相变的最简单的统计模型之一。

考虑一组 $\Lambda$ 个晶格点，每个点都有一组相邻点（例如一个图）形成一个 $d$ 维晶格。对于每个晶格点 $k \in \Lambda$，都有一个离散变量 $\sigma_k$，使得 $\sigma_k \in\{-1,+1\}$，表示点的自旋。自旋配置 $\sigma=\left\{\sigma_k\right\}_{k \in \Lambda}$ 是每个晶格点的自旋值分配。对于任何两个相邻位置 $i, j \in \Lambda$，存在相互作用 $J_{i j}$。此外，位置 $j \in \Lambda$ 有一个外部磁场 $h_j$ 与其相互作用。配置 $\sigma$ 的能量由哈密顿函数给出：
$$
H(\sigma)=-\sum_{\langle i j\rangle} J_{i j} \sigma_i \sigma_j-\mu \sum_j h_j \sigma_j
$$
其中第一个和是对相邻自旋对的和（每对都计算一次）。符号 $\langle i j\rangle$ 表示位置 $i$ 和 $j$ 是最近的邻居。磁矩由 $\mu$ 给出。请注意，上面哈密顿量的第二项中的符号实际上应该是正的，因为电子的磁矩与其自旋反向平行，但通常使用负项。配置概率由温度倒数为 $\beta \geq 0$ 的玻尔兹曼分布给出：
$$
P_\beta(\sigma)=\frac{e^{-\beta H(\sigma)}}{Z_\beta}
$$
其中 $\beta=1 /\left(k_{ B } T\right)$，归一化常数
$$
Z_\beta=\sum_\sigma e^{-\beta H(\sigma)}
$$
是配分函数。对于自旋函数 $f$（“可观测”），我们表示为
$$
\langle f\rangle_\beta=\sum_\sigma f(\sigma) P_\beta(\sigma)
$$
$f$ 的期望（均值）。

配置概率 $P_\beta(\sigma)$ 表示系统（在平衡状态下）处于配置 $\sigma$ 状态的概率。

### 二维模型模拟

```Python
import numpy as np
from numpy.random import rand
import matplotlib.pyplot as plt
```

```Python
def initialstate(N):   
    state = 2*np.random.randint(2, size=(N,N))-1
    return state


def mcmove(config, beta):
    for i in range(N):
        for j in range(N):
                a = np.random.randint(0, N)
                b = np.random.randint(0, N)
                s =  config[a, b]
                nb = config[(a+1)%N,b] + config[a,(b+1)%N] + config[(a-1)%N,b] + config[a,(b-1)%N]
                cost = 2*s*nb
                if cost < 0:
                    s *= -1
                elif rand() < np.exp(-cost*beta):
                    s *= -1
                config[a, b] = s
    return config


def calcEnergy(config):
    energy = 0
    for i in range(len(config)):
        for j in range(len(config)):
            S = config[i,j]
            nb = config[(i+1)%N, j] + config[i,(j+1)%N] + config[(i-1)%N, j] + config[i,(j-1)%N]
            energy += -nb*S
    return energy/4.


def calcMag(config):
    mag = np.sum(config)
    return mag
```

更改这些参数以实现更小（更快）的模拟

```Python
nt      = 88         
N       = 16         
eqSteps = 1024       
mcSteps = 1024       

T       = np.linspace(1.53, 3.28, nt); 
E,M,C,X = np.zeros(nt), np.zeros(nt), np.zeros(nt), np.zeros(nt)
n1, n2  = 1.0/(mcSteps*N*N), 1.0/(mcSteps*mcSteps*N*N) 
```

```Python
for tt in range(nt):
    E1 = M1 = E2 = M2 = 0
    config = initialstate(N)
    iT=1.0/T[tt]; iT2=iT*iT;
    
    for i in range(eqSteps):         
        mcmove(config, iT)          

    for i in range(mcSteps):
        mcmove(config, iT)           
        Ene = calcEnergy(config)     
        Mag = calcMag(config)        

        E1 = E1 + Ene
        M1 = M1 + Mag
        M2 = M2 + Mag*Mag 
        E2 = E2 + Ene*Ene

    E[tt] = n1*E1
    M[tt] = n1*M1
    C[tt] = (n1*E2 - n2*E1*E1)*iT2
    X[tt] = (n1*M2 - n2*M1*M1)*iT
```

```Python
f = plt.figure(figsize=(18, 10));   

sp =  f.add_subplot(2, 2, 1 );
plt.scatter(T, E, s=50, marker='o', color='IndRed')
plt.xlabel("Temperature (T)", fontsize=20);
plt.ylabel("Energy ", fontsize=20);         plt.axis('tight');

sp =  f.add_subplot(2, 2, 2 );
plt.scatter(T, abs(M), s=50, marker='o', color='RoyalBlue')
plt.xlabel("Temperature (T)", fontsize=20); 
plt.ylabel("Magnetization ", fontsize=20);   plt.axis('tight');

sp =  f.add_subplot(2, 2, 3 );
plt.scatter(T, C, s=50, marker='o', color='IndianRed')
plt.xlabel("Temperature (T)", fontsize=20);  
plt.ylabel("Specific Heat ", fontsize=20);   plt.axis('tight');   

sp =  f.add_subplot(2, 2, 4 );
plt.scatter(T, X, s=50, marker='o', color='RoyalBlue')
plt.xlabel("Temperature (T)", fontsize=20); 
plt.ylabel("Susceptibility", fontsize=20);   plt.axis('tight');
```
### :point_right:[亞圖跨際更多視角](https://viadean.notion.site/Python-CUDA-C-11f1ae7b9a32804a9cd4c5c9d4ffc86a)