You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ProbLog中表示指定1占比的二进制向量的p事实/规则

ProbLog下二进制随机向量的正确建模方案

基础定义(p-fact/p-rule 实现)

你最开始写的单向量代码是单个向量的正确实现:

% 单向量场景,N=1000,P=20,每个位为1的概率0.02
0.02::one(X) :- between(1,1000,X).

如果需要处理多个向量,必须增加向量ID参数区分不同向量的独立事件,同时支持参数化P/N,完整写法如下:

% 参数化概率规则:第VID个向量的第Bit位为1的概率 = P/N
% 入参说明:VID=向量唯一ID,P=期望1的个数,N=向量总长度,Bit=位索引(1~N)
{P/N}::vec_bit(VID, P, N, Bit) :- between(1, N, Bit).

% 可选:批量定义向量ID,M替换为你需要的向量总数即可
vector_id(VID) :- between(1, M, VID).

该写法同时兼容cplint,逻辑完全一致。

常用向量运算的建模实现

你需要的各类运算可以直接基于上面的基础规则扩展:

  • 两个向量对应位AND运算
% 向量V1和V2的第Bit位AND结果为1
vec_and(V1, V2, P, N, Bit) :-
    vec_bit(V1, P, N, Bit),
    vec_bit(V2, P, N, Bit).
  • 两个向量对应位OR运算
% 向量V1和V2的第Bit位OR结果为1
vec_or(V1, V2, P, N, Bit) :- vec_bit(V1, P, N, Bit).
vec_or(V1, V2, P, N, Bit) :- vec_bit(V2, P, N, Bit).
  • 两个向量对应位XOR运算
% 向量V1和V2的第Bit位XOR结果为1
vec_xor(V1, V2, P, N, Bit) :- vec_bit(V1, P, N, Bit), \+ vec_bit(V2, P, N, Bit).
vec_xor(V1, V2, P, N, Bit) :- \+ vec_bit(V1, P, N, Bit), vec_bit(V2, P, N, Bit).
  • 汉明距离计算
% 两个向量V1、V2的汉明距离为Dist
hamming_dist(V1, V2, P, N, Dist) :-
    findall(1, vec_xor(V1, V2, P, N, _Bit), Ones),
    length(Ones, Dist).
  • 多向量OR运算
% 向量列表[V1,V2,...Vk]的OR结果第Bit位为1
multi_or([V|_Rest], P, N, Bit) :- vec_bit(V, P, N, Bit).
multi_or([_V|Rest], P, N, Bit) :- multi_or(Rest, P, N, Bit).
  • 重叠计数(两个向量同时为1的位数量)
% 向量V1和V2的重叠1的数量为Cnt
overlap_cnt(V1, V2, P, N, Cnt) :-
    findall(1, vec_and(V1, V2, P, N, _Bit), Ones),
    length(Ones, Cnt).

典型查询场景示例

以你提到的「10个随机向量做OR运算后,和新随机向量的重叠计数」场景为例,完整实现:

% 定义11个向量,N=1000,P=20(每个位概率20/1000=0.02)
vector_id(VID) :- between(1, 11, VID).
{P/N}::vec_bit(VID, P, N, Bit) :- between(1, N, Bit), vector_id(VID).

% 前10个向量的OR结果的第Bit位为1
or_10(P, N, Bit) :- multi_or([1,2,3,4,5,6,7,8,9,10], P, N, Bit).

% OR结果和第11个新向量的重叠计数
or_overlap_cnt(P, N, Cnt) :-
    findall(1, (or_10(P, N, Bit), vec_bit(11, P, N, Bit)), Ones),
    length(Ones, Cnt).

% 查询:重叠计数为5的概率
query(or_overlap_cnt(20, 1000, 5)).
% 查询:重叠计数的期望值
query(expected(or_overlap_cnt(20, 1000, Cnt), Cnt)).

你现有代码的问题修正

你之前参考的代码核心错误是把Bit位设为匿名变量,导致所有位共享同一个随机变量,不是独立事件。修正后的prob_on规则如下:

{P/N}::vec_bit(VID, P, N, Bit) :- between(1, N, Bit).

% 检查向量1的位列表List1、向量2的位列表List2中所有位都为1的概率
prob_on(List1, List2, P, N) :-
    maplist(vec_bit(1, P, N), List1),
    maplist(vec_bit(2, P, N), List2).

% 你的查询示例:输出结果为(2/10)*(2/10)=0.04,符合预期
query(prob_on([1], [1], 2, 10)).
query(prob_on([1,2,3,5],[1,6,9,2],2,10)).

内容的提问来源于stack exchange,提问作者sten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 07:24:00