Gumdrop 发布的文章

题目

【见附件,来源水群】

方法1

每个时间段有十九种状态且每个状态的概率是之前时间的状态的函数,直觉上要用动态规划

#include<iostream>
#include<chrono>

using namespace std;
const int tmax = 6000, lenmax = 18;
double pot[tmax + 1][lenmax + 1];             //储存所有状态

int main()
{
    auto RUNTIME1 = chrono::system_clock::now();

    pot[0][12] = 1;
    for (int i = 1; i <= tmax; ++i) {       //从初始态逐步计算到目标时间
        for (int j = 1; j < lenmax; ++j) {    //每个状态通过题目给出状态转移的方法进行计算
            double p = pot[i - 1][j];
            if (j < 9) {
                pot[i][j - 1] += p * 0.4;
                pot[i][j + 1] += p * 0.6;
            }
            else if (j == 9) {
                pot[i][j - 1] += p * 0.5;
                pot[i][j + 1] += p * 0.5;
            }
            else {
                pot[i][j - 1] += p * 0.6;
                pot[i][j + 1] += p * 0.4;
            }
        }
    }

    const int term = tmax / 60;
    double ans1 = 0;
    for (int i = 1; i <= term; ++i) {
        ans1 = 0;
        int T = i * 60;
        for (int j = 1; j < lenmax; ++j) {
            ans1 += pot[T][j];
        }
        cout << i << "min后持续的概率: " << ans1 << endl;
    }

    double ans2[tmax + 1] = { 0 };
    for (int j = 1; j <= term; ++j) {
        int I = j * 60;
        for (int i = 1 + (j - 1) * 60; i <= I; ++i) {
            ans2[j] += (pot[i][0] + pot[i][lenmax]) * i;
        }
    }
    for (int i = 1; i <= term; ++i) {
        cout << "第" << i << "分钟内的期望子式: " << ans2[i] << endl;
    }

    double ans3 = 0;
    for (int i = 1; i <= term; ++i) {
        ans3 += ans2[i];
    }
    cout << "当前计算期望值: " << ans3 << ", " << "误差: " << ans2[term] / ans3 * 100 << '%' << endl;

    cout << term << "min概率: " << ans1 << endl;

    double ans4 = ans1;
    for (int i = 1; i <= tmax; ++i) {
        ans4 += pot[i][0] + pot[i][lenmax];
    }
    cout << "总概率: " << ans4 << endl;

    auto RUNTIME2 = chrono::system_clock::now();
    cout << "用时" << (RUNTIME2 - RUNTIME1).count() << "us" << endl;
}

通过对100min内期望的计算可以猜测期望子式和收敛于某个值,该值即为数学期望。表达式有无数个子式。

耗时约0.6s,在8min时约70ms,应该不会超时,不作进一步优化。

结果

屏幕截图 2025-03-20 193444.png

屏幕截图 2025-03-20 193455.png

方法2

用矩阵描述状态转移(状态转移矩阵)。

M=zeros(19,19)
for i=2:9
    M(i-1,i)=0.4
    M(i+1,i)=0.6
end
M([9,11],10)=0.5
for i=11:19
    M(i-1,i)=0.6
    M(i+1,i)=0.4
end

初始状态为:

S=zeros(19,1)
S(13)=1

第n秒各状态的概率:

M^n*S

要求停止的数学期望,即状态1和19的和乘以时间n:

Select=zeros(1,19)
Select([1,19])=1
Select*M^n*S

求极限

由于矩阵的指数不能为sym类型,先对角化:

[V,D]=eig(M)%MV=VD,M=VDV^-1,M^n=VD.^nV^-1

求极限:

syms n
f=Select*V*D.^n*V^-1*S
limit(f,n,inf)%结果为0

对该数列求极限为0,可能收敛。

求和的极限:

symsum(f,n,inf)

值和方法1完全不同。检查发现在10s内的结果完全相同,随时间延长到60s时已出现在千分位的不同,到480s时已经完全不同。

误差原因

可能由于对角化时对数位的圆整,或在初始状态后发生了显示0的元只是很小的浮点型的情况。

背景

opencv是主要用于计算机视觉、也可用于图像绘制和处理的包,可用c++和python等调用。

ffmpeg是用于视频处理等的包,opencv可以用ffmpeg处理一些视频文件并提取视频帧进行处理,再生成视频。

如果ffmpeg版本不合适则opencv不能处理视频文件,而ffmpeg本身语法实在太难,在只提取视频帧的情况下最好不要学ffmpeg。

使用opencv.org下载的opencv要和合适版本的ffmpeg同时编译才能使用,版本对应要手动控制。

vcpkg安装带ffmpeg特性的opencv,是不用手动调节ffmpeg版本与opencv版本对应的,只要选择合适版本的opencv即可。

目的

使用vcpkg安装opencv[ffmpeg]并成功打开mp4视频文件。

涉及到的目录和文件:

  • ${VCPKG_ROOT}\ports\

  • ${VCPKG_ROOT}\versions\

  • ${SolutionDir}\vcpkg.json

  • ${SolutionDir}\vcpkg_installed\

注意事项

通常的安装方式安装的vcpkg,都会使用Git包注册表,使用时需科学上网到github。会自动使用http代理。

最新版本不能用,使用3.4.3-9版本的opencv。opencv2没有ffmpeg,opencv4似乎也没用。

路径没有空格,防止命令行参数错误。

步骤

  1. 安装好vcpkg和找好访问github的方法。

  2. vcpkg install opencv[ffmpeg]:x64-windows会安装4.10版本,不能用。要改变vcpkg根目录使用的port版本要使用git命令回退版本,跳过。使用清单模式在项目上安装opencv。

  3. 在visual studio项目命令行。

    vcpkg new --application
    
  4. 手动编辑vcpkg.json(项目清单)。

    {
        "dependencies":[
            {
                "name":"opencv",
                "features":[
                    "ffmpeg"
                ]
            }
        ],
        "overrides":[
            {
                "name":"opencv",
                "version":"3.4.3-9"
            }
        ]
    }
    
  5. 在vcxproj文件中添加设置使用清单模式(在VS没有安装vcpkg时)。

    <PropertyGroup Label="Vcpkg">
      <VcpkgEnableManifest>true</VcpkgEnableManifest>
    </PropertyGroup>
    
  6. 配置vcpkg到msbuild。

    vcpkg integrate install
    
  7. 安装opencv[ffmpeg]包文件到项目。

    vcpkg install
    
  8. 打开sln,此时会自动把项目目录中的包含文件目录、依赖项目录等添加到项目属性。可以正常编写程序并调用函数。

  9. 示例程序:

    #include<opencv2/opencv.hpp>
    
    int main() {
        cv::namedWindow("eg", cv::WINDOW_AUTOSIZE);
        cv::VideoCapture cap("2.mp4");
        std::cout << cap.isOpened() << ' ' << cap.get(CV_CAP_PROP_FPS);
        double fps = cap.get(CV_CAP_PROP_FPS);
        cv::Mat frame;
        for (;;) {
            cap >> frame;
            if (frame.empty())break;
            cv::imshow("eg", frame);
            if (cv::waitKey(1000.0 / fps) >= 0)break;
        }
        cap.release();
    }
    

2656bbaa-39b0-44b5-a507-d454309e79bc.png

缺陷

  • 相比正常安装方式,不能确定高版本不能编译出opencv_ffmpeg.dll的原因和解决方案。

  • vcpkg通常只用在windows。

  • 项目体积大,vs体积大,vcpkg目录体积大。

  • 配置项目环境巨慢。

结论

还能用。

参考文献

vcpkg安装的opencv读取视频 - 简书

教程:从清单文件安装依赖项 | Microsoft Learn

步骤

  1. 修改docker run语句启动容器 91c83eff-7d46-4afd-a329-7cdd5e25abb5.png Copy docker run复制启动语句,其中有--volumn:/xiaomusic_music=/app/music等,功能是实现容器与主机共享文件夹(挂载bind mount)。 将/xiaomusic_music修改为主机储存音乐的文件夹的目录,以该语句启动新容器即可。/xiaomusic_conf同理。

  2. 静态ip地址的设定 设备每次接入局域网都被分配不同ip。通过命令行输入ipconfig可以查询局域网下本机ip和网关ip(路由器),浏览器输入网关ip可以进入路由器管理界面,输入密码(路由器背面)可以设置当前设备的静态ip。

完成界面

5597c29c-1e6d-48ae-b593-e8cca49ba335.png

2d5bc023-8318-4e1c-8806-bea0c2dda87f.png

4b3fe78e-17de-423e-8cc7-d2f6cc94d32f.png

结论

不如蓝牙(需要NAS),感觉如果有usb接口问题就好解决太多了。

背景

小米音箱作为米家的一款智能音箱,具有声控、联网查歌等功能。但是通过仔细搜查发现,小米音箱不具有播放本地音乐的功能,其附带app上的歌单,音乐文件并不在本地,而是通过链接直接联网获取,因此不能通过安卓端直接导入音乐文件。

目的

通过github仓库XiaoMusic,实现小米音箱播放PC(windows)中的音乐。

主要软件、网站

  1. Github 阅读作者的教程和Q&A。

  2. docker desktop 作为实现功能的重要软件,图形化界面管理容器,并且从服务器直接导入镜像等。

  3. v2rayN 以上软件、网站都需要该软件访问。

  4. deepseek 想不通就问。

步骤

  1. 配置v2rayN(略)

  2. 安装docker desktop of windows(dfw) 默认的硬盘映像文件在C:,可以在应用内调为D:。

  3. 在dfw内的终端输入教程中的docker run ...语句 计算机终端不能直接通过v2代理,使用dfw更方便。

  4. 启动容器 a9521b93-785e-449d-97e3-e859c39f178a.png 从上到下依次为容器名、容器id、容器界面链接,点击链接进入容器的界面,可以使用图形化界面调整参数。如果使用了v2将无法进入图形界面。 重点有:输入的账号必须已经在小米音箱app中连接了目标音箱;ip地址填开启容器的计算机在局域网中地址(不能是localhost);音箱必须和PC在局域网内。

  5. 此时可以从网络(默认bilisearch)查找并下载音乐。

剩余问题

  1. wifi不区分2.4G和5G。
  2. 每次打开容器需要重新配置参数。
  3. 歌曲依然不能读取本地,且下载过的音乐不会保存下来。
  4. 计算机在局域网中不具有静态ip地址。

在网上找一堆稀奇古怪东东都搞不定之后研究文档得到一简单方法。

fittype能创建一个自定义线性模型,使用方法:

fittype({'x','sin(x)','1'})

线性模型是:

$$ ax+b\sin(x)+c $$

所以只要创建一个ax模型拿去用就可以了。

ft=fittype({'x'})
f=fit(m,U,ft)