这个头衔可能没有意义。假设如下:
在这种基本情况下,有三个交易,但可以减少到两个交易:
考虑到更复杂的图表,存在哪些算法可以最小化事务总数?
答案 0 :(得分:9)
在我看来,首先要弄清楚每个人在所有交易发生后上升/下降的程度。对于你的例子,那将是:
A : -5
B : 0
C : -10
D : +15
一旦你拥有了它,你只需要将它们全部归零。获取最高收益,并开始增加损失。在这一点上,它基本上是一个装箱问题。
答案 1 :(得分:0)
它可能效率低下,但您可以使用整数编程。
预计算进入/离开节点i的净流量,即Fi =总债务+总信用额
设M是一个很大的数字。
让Yij为决策变量,表示我支付给节点j(有序对)的金额节点。
让Xij为二进制变量,表示在i&之间发生了一次交易。 j(无序对)
优化以下内容:
min sum_ {i,j} Xij
sum_ {j!= i} Yij = Fi
Yij + Yji =< = M * Xij
答案 2 :(得分:0)
你可以尝试贪婪的方法。所以
如果A欠B,B欠B,那么A欠C的最小值(A-> B,B-> C)。并且A-> B- = min(A-> B,B-> C)。如果在此操作之后A-> B变为zero
,则将其删除。循环,直到你无法执行任何进一步的操作,即图中没有cycles
。:
do{
bool stop = true;
G.init() // initialize some sort of edge iterator
while(edge = G.nextedge()){ //assuming nextedge will terminate after going through all edges once
foreach(outedge in edge.Dest.Outedges){ //If there's any node to 'move' the cost
minowed = min(edge.value, outedge.value)
G.edge(edge.Src, outedge.Dest).value += minowed
edge.value -= minowed
outedge.value -= minowed
if(edge.value == 0) G.remove(edge)
if(outedge.value == 0) G.remove(outedge)
stop = false
}
}
}while(!stop)
这相当于从图表中删除任何周期,使其成为DAG
。