最优传输学习及问题总结

文章目录

  • 参考内容
  • lam=0.1
  • lam=3
  • lam=10
  • lam=50
  • lam=100
  • lam=300
  • 画图
  • 线性规划
    • matlab
    • python代码

欢迎关注我们组的微信公众号,更多好文章在等你呦!
微信公众号名:碳硅数据
公众号二维码:
在这里插入图片描述

参考内容

https://blog.csdn.net/qq_41129489/article/details/128830589
https://zhuanlan.zhihu.com/p/542379144

我主要想强调的是这个例子的解法存在的一些细节问题

lam=0.1

lam = 0.1

P, d = compute_optimal_transport(M,
        r,
        c, lam=lam)

partition = pd.DataFrame(P, index=np.arange(1, 9), columns=np.arange(1, 6))
ax = partition.plot(kind='bar', stacked=True)
print('Sinkhorn distance: {}'.format(d))
ax.set_ylabel('portions')
ax.set_title('Optimal distribution ($\lambda={}$)'.format(lam))

print(d)

PP = np.around(P,3) 
print(PP)

print("*"*100)
print(np.sum(PP,axis=0))
print(np.sum(PP,axis=1))
print("*"*100)
## 这个很接近了

结果如下
在这里插入图片描述

lam=3

lam = 3

P, d = compute_optimal_transport(M,
        r,
        c, lam=lam)

partition = pd.DataFrame(P, index=np.arange(1, 9), columns=np.arange(1, 6))
ax = partition.plot(kind='bar', stacked=True)
print('Sinkhorn distance: {}'.format(d))
ax.set_ylabel('portions')
ax.set_title('Optimal distribution ($\lambda={}$)'.format(lam))
print(d)

PP = np.around(P,3) 
print(PP)

print("*"*100)
print(np.sum(PP,axis=0))
print(np.sum(PP,axis=1))
print("*"*100)
## 这个很接近了

在这里插入图片描述

lam=10

lam = 10

P, d = compute_optimal_transport(M,
        r,
        c, lam=lam)

partition = pd.DataFrame(P, index=np.arange(1, 9), columns=np.arange(1, 6))
ax = partition.plot(kind='bar', stacked=True)
print('Sinkhorn distance: {}'.format(d))
ax.set_ylabel('portions')
ax.set_title('Optimal distribution ($\lambda={}$)'.format(lam))

print(d)

PP = np.around(P,3) 
print(PP)

print("*"*100)
print(np.sum(PP,axis=0))
print(np.sum(PP,axis=1))
print("*"*100)
## 这个很接近了

在这里插入图片描述

lam=50

lam = 50

P, d = compute_optimal_transport(M,
        r,
        c, lam=lam)

partition = pd.DataFrame(P, index=np.arange(1, 9), columns=np.arange(1, 6))
ax = partition.plot(kind='bar', stacked=True)
print('Sinkhorn distance: {}'.format(d))
ax.set_ylabel('portions')
ax.set_title('Optimal distribution ($\lambda={}$)'.format(lam))

PP = np.around(P,3) 
print(PP)

print("*"*100)
print(np.sum(PP,axis=0))
print(np.sum(PP,axis=1))
print("*"*100)
## 这个很接近了

在这里插入图片描述

lam=100

lam = 100

P, d = compute_optimal_transport(M,
        r,
        c, lam=lam)

partition = pd.DataFrame(P, index=np.arange(1, 9), columns=np.arange(1, 6))
ax = partition.plot(kind='bar', stacked=True)
print('Sinkhorn distance: {}'.format(d))
ax.set_ylabel('portions')
ax.set_title('Optimal distribution ($\lambda={}$)'.format(lam))

print(d)
PP = np.around(P,3) 
print(PP)

print("*"*100)
print(np.sum(PP,axis=0))
print(np.sum(PP,axis=1))
print("*"*100)
## 这个很接近了

在这里插入图片描述

lam=300

lam = 300

P, d = compute_optimal_transport(M,
        r,
        c, lam=lam)

partition = pd.DataFrame(P, index=np.arange(1, 9), columns=np.arange(1, 6))
ax = partition.plot(kind='bar', stacked=True)
print('Sinkhorn distance: {}'.format(d))
ax.set_ylabel('portions')
ax.set_title('Optimal distribution ($\lambda={}$)'.format(lam))

print(d)
PP = np.around(P,3) 
print(PP)

print("*"*100)
print(np.sum(PP,axis=0))
print(np.sum(PP,axis=1))
print("*"*100)
## 这个就不接近了,之前的求和都是相差在0.001左右,可以近似看作相等
## 但是这个行和是 [2.    1.714 3.75  2.286 2.5   2.5   4.    1.25 ]
## 很明显是 [3. 3. 3. 4. 2. 2. 2. 1.]这个是不对的,所以lam=300时这个值已经发散了,
## 虽然此时的Sinkhorn distance是小于24的,但也不起作用

在这里插入图片描述

画图

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def compute_optimal_transport(M=None, r=None, c=None, lam=None, eplison=1e-8):
    """
    Computes the optimal transport matrix and Slinkhorn distance using the
    Sinkhorn-Knopp algorithm

    Inputs:
        - M : cost matrix (n x m)
        - r : vector of marginals (n, )
        - c : vector of marginals (m, )
        - lam : strength of the entropic regularization
        - epsilon : convergence parameter

    Outputs:
        - P : optimal transport matrix (n x m)
        - dist : Sinkhorn distance
    """
    r = np.array([3, 3, 3, 4, 2, 2, 2, 1])
    c = np.array([4, 2, 6, 4, 4])
    M = np.array(
        [[2, 2, 1, 0, 0], 
        [0, -2, -2, -2, -2], 
        [1, 2, 2, 2, -1], 
        [2, 1, 0, 1, -1],
        [0.5, 2, 2, 1, 0], 
        [0, 1, 1, 1, -1], 
        [-2, 2, 2, 1, 1], 
        [2, 1, 2, 1, -1]],
        dtype=float) 
    M = -M # 将M变号,从偏好转为代价
    
    
    n, m = M.shape  # 8, 5
    P = np.exp(-lam * M) # (8, 5)
    P /= P.sum()  # 归一化
    u = np.zeros(n) # (8, )
    # normalize this matrix
    while np.max(np.abs(u - P.sum(1))) > eplison: # 这里是用行和判断收敛
        # 对行和列进行缩放,使用到了numpy的广播机制,不了解广播机制的同学可以去百度一下
        u = P.sum(1) # 行和 (8, )
        P *= (r / u).reshape((-1, 1)) # 缩放行元素,使行和逼近r
        v = P.sum(0) # 列和 (5, )
        P *= (c / v).reshape((1, -1)) # 缩放列元素,使列和逼近c
    return P, np.sum(P * M) # 返回分配矩阵和Sinkhorn距离

lam_list=[1,5,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150]

cost_list=[]
for lam in lam_list:
    P, d = compute_optimal_transport(lam=lam)
    cost_list.append(d)
print(cost_list)
plt.plot(np.array(lam_list),np.array(cost_list),c="g")
plt.show()

## 现在这个地方也有的

在这里插入图片描述
这个地方其实有一个画图的小问题,我待会要再写一下

可以看到大概是在lam =150的时候,就已经不稳定了,所以这个例子的问题的解的最小花费约等于24,但是我发现一个更有意思的问题,就是这个分配矩阵是唯一的吗,很显然不是的, 利用我上篇文章学到的线性规划,我发现matlab和python找到的是两个不同的解,

线性规划

matlab

clc;
clear;

r = [3, 3, 3, 4, 2, 2, 2, 1];
c = [4, 2, 6, 4, 4];
cost_matrix =  [2, 2, 1, 0, 0;
             0, -2, -2, -2, -2; 
               1, 2, 2, 2, -1;
               2, 1, 0, 1, -1;
              0.5, 2, 2, 1, 0;
               0, 1, 1, 1, -1;
               -2, 2, 2, 1, 1;
              2, 1, 2, 1, -1];

cost_matrix_t = (-1)*transpose(cost_matrix);% 需要有符号
cost_vec = cost_matrix_t(:);

raw_equ = zeros(8,40);
for i =1:8
    raw_equ(i,((i-1)*5+1):((i-1)*5+5))=1;
end

col_equ = zeros(5,40);
for i =1:5
    for j =1:8
        col_equ(i,i+(j-1)*5)=1;
    end
end

equ = [raw_equ;col_equ];
equ_value = horzcat(r, c);
% x1,x2,x3,x4,x5
% x6,x7,x8,x9,x10
% x11,x12,x13,x14,x15
% x16,x17,x18,x19,x20
% x21,x22,x23,x24,x25
% x26,x27,x28,x29,x30
% x31,x32,x33,x34,x35
% x36,x37,x38,x39,x40

% 现在我要求的变量是这样的,
f=cost_vec;			% 价值向量
a=[];	% a、b对应不等式的左边和右边
b=[];
aeq=equ;	% aeq和beq对应等式的左边和右边
beq=equ_value;
[x,y]=linprog(f,a,b,aeq,beq,zeros(40,1));

arr_mat = transpose(reshape(x',5,8));

结果如下
在这里插入图片描述
分配矩阵如下在这里插入图片描述

python代码

# Define parameters
m = 8
n = 5

p = np.array([3, 3, 3, 4, 2, 2, 2, 1])
q = np.array([4, 2, 6, 4, 4])

C = -1*np.array(
    [[2, 2, 1, 0, 0], 
    [0, -2, -2, -2, -2], 
    [1, 2, 2, 2, -1], 
    [2, 1, 0, 1, -1],
    [0.5, 2, 2, 1, 0], 
    [0, 1, 1, 1, -1], 
    [-2, 2, 2, 1, 1], 
    [2, 1, 2, 1, -1]],
    dtype=float)

# Vectorize matrix C
C_vec = C.reshape((m*n, 1), order='F')

# Construct matrix A by Kronecker product
A1 = np.kron(np.ones((1, n)), np.identity(m))
A2 = np.kron(np.identity(n), np.ones((1, m)))
A = np.vstack([A1, A2])

# Construct vector b
b = np.hstack([p, q])

# Solve the primal problem
res = linprog(C_vec, A_eq=A, b_eq=b)

# Print results
print("message:", res.message)
print("nit:", res.nit)
print("fun:", res.fun)
print("z:", res.x)
print("X:", res.x.reshape((m,n), order='F'))

结果如下
在这里插入图片描述
可以看到花费都是24,但是两者的分配矩阵并不一样哈

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/340414.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu下安装Gazebo仿真器

Ubuntu下安装Gazebo仿真器 Gazebo仿真平台通常需要配合ROS使用,因此需要先安装ROS。可以参考ROS安装教程 首先安装一些必要的工具 sudo apt-get update sudo apt-get install lsb-release wget gnupg修改源 sudo wget https://packages.osrfoundation.org/gazebo…

【教程】npm的时候ssh报错ssh://git@github.com/frozeman/bignumber.js-nolookahead.git

问题: fiscoubuntu:~/fisco/benchmarks$ npm install install web30.20.7 npm ERR! code 128 npm ERR! An unknown git error occurred npm ERR! command git --no-replace-objects ls-remote ssh://gitgithub.com/frozeman/bignumber.js-nolookahead.git npm ERR! …

UE5 Windows打包时报错“SDK Not Found”解决方案

在Unreal Engine 5.0.3 Windows平台下打包时报错:“Windows的SDK未正常安装,而其是生成数据的必需项。请检查主工具栏中“启动“菜单SDK部分来更新SDK。” 解决方案: 1、打开 Visual Studio Installer,点击“修改”按钮&#xf…

【技术分享】远程透传网关-单网口快速实现西门子S7-1200/1500 PLC程序远程上下载

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条,用于实现网络连接和连接PLC一台西门子S7-1200/1500 PLC及其编程软件一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡,WIFI联网则将WIFI天线插入USB口&…

jieba.net使用NuGet管理器安装后初始化TfidfExtractor对象时报错

在引用安装jieba.net后,引用的Resources下只有如图几个文件 导致初始化TfidfExtractor时报错,报找不到 Could not find file E:\\TZKJNet\\robotindustry\\modules\\Tzkj.Superhard.SupplyDemand\\src\\Tzkj.Superhard.SupplyDemand.HttpApi.Host\\bin\\Debug\\net7.0\\Reso…

SpringSecurity(11)——核心组件和认证流程

获取用户信息 // 获取安全上下文对象,就是那个保存在 ThreadLocal 里面的安全上下文对象 // 总是不为null(如果不存在,则创建一个authentication属性为null的empty安全上下文对象) SecurityContext securityContext SecurityContextHolder.getContext(…

JS进阶-作用域、垃圾回收机制、闭包、变量提升(一)

• 作用域 作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问 作用域分为: 局部作用域 全局作用域 • 局部作用域 局部作用域分为函数作用域和块作用域。 1. 函数作用域: 在函数内…

Kafka常见指令及监控程序介绍

kafka在流数据、IO削峰上非常有用,以下对于这款程序,做一些常见指令介绍。 下文使用–bootstrap-server 10.0.0.102:9092,10.0.0.103:9092,10.0.0.104:9092 需自行填写各自对应的集群IP和kafka的端口。 该写法 等同 –bootstrap-server localhost:9092 …

RabbitMQ数据隔离

1、新建用户 2、登录用户,设置虚拟主机 登录用户只能操作自己的虚拟主机,交换机等,不能操作其他人的!!!

【立创EDA-PCB设计基础】3.网络表概念解读+板框绘制

前言:本文对网络表概念解读板框绘制(确定PCB板子轮廓) 网络表概念解读 在本专栏的上一篇文章【嘉立创EDA-PCB设计指南】2,将设计的原理图转为了PCB,在PCB界面下出现了所有的封装,以及所有的飞线属性&…

MSI模块应用:可变N进制计数器设计

将集成组合逻辑电路模块和时序逻辑电路模块结合起来实现某种电路功能,一般多见于译码器、数据选择器和计数器的综合应用,以实现节拍信号发生器或序列信号发生器。本文介绍另一种题型,即数值比较器和计数器的综合应用。(典型试题&a…

最全笔记软件盘点!你要的笔记神器都在这里:手写笔记、知识管理、文本笔记、协作笔记等!

在当今的信息化社会中,人们对信息的处理速度越来越快,从工作到生活,我们都面临着大量信息的冲击。在这样的环境下,一个能够帮助我们管理、整理和储存信息的好工具显得尤为重要,而笔记软件恰恰可以满足这些需求。 在选…

在IDEA中使用快捷键让XML注释更加规范

Setting -> Editor -> Code Style -> XML 取消勾选 Line comment at first column 这样我们在使用ctrl / 快速注释时,就可以让注释符号紧贴注释内容,不出现空格。

vue+elementUI el-select 中 没有加clearable出现一个或者多个×清除图标问题

1、现象:下方截图多清除图标了 2、在全局common.scss文件中加一个下方的全局样式noClear 3、在多清除图标的组件上层div加noClear样式 4、清除图标去除成功

【C++进阶07】哈希表and哈希桶

一、哈希概念 顺序结构以及平衡树中 元素关键码与存储位置没有对应关系 因此查找一个元素 必须经过关键码的多次比较 顺序查找时间复杂度为O(N) 平衡树中为树的高度,即O( l o g 2 N log_2 N log2​N) 搜索效率 搜索过程中元素的比较次数 理想的搜索方法&#xff1a…

知识库是什么:中小型企业都要知道的重要讯息

在当今信息爆炸的年代,久而久之,企业可能发现自己沉浸在各种信息、学习资料和数据中。这就使得组织和管理这些信息变得尤为重要。进入我们的视线的就是“知识库”,它其实就像一个企业自己的“小图书馆”,只不过,这个库…

如何提取3D动画中的模型---模大狮模型网

在现代媒体制作和设计领域,3D动画已经成为一种常见的表达方式。如果您对一部3D动画中的某个特定模型非常感兴趣,并且想要提取出来以便进行后续操作或学习,模大狮将向您介绍一些方法和步骤。 一、选择适当的软件 要提取3D动画中的模型&#x…

Vue (v-bind指令、el与data的两种写法、理解MVVM、数据代理、V-no事件处理、双向数据绑定V-model、登陆页面实现

V-bind指令 el与data两种写法 MVVM 数据代理 V-no事件处理 V-no用于监听DOM对象 双向数据绑定V-model v-model 指令用来在 input、select、textarea、checkbox、radio 等表单控件元素上创建双向数据绑定,根据表单上的值,自动更新绑定的元素的值。 按钮的…

【MATLAB】ICEEMDAN+FFT+HHT组合算法

代码基本原理 ICEEMDAN(改进的完全经验模态分解与自适应噪声)FFT(快速傅里叶变换)HHT(希尔伯特-黄变换)组合算法是一种用于信号处理和分析的复杂组合算法。它结合了ICEEMDAN、FFT和HHT三个步骤&#xff0c…

ChatGLM3报错:No chat template is defined for this tokenizer

使用官方提供的脚本创建ChatGLM3的DEMO&#xff1a; cd basic_demo python web_demo_gradio.py 出现效果异常问题&#xff1a; conversation [{role: user, content: 你好}, {role: assistant, content: 你好&#xff0c;有什么我可以帮助你的吗&#xff1f;\n\n<|im_end|…