Java 搜索算法-桶和石头
嗨,我正在搜索一个算法来解决以下问题: 有n个桶和y个石头,可以扔进桶里。每个学生在随机的桶中投掷石头x次后,桶中的石头数量不同。现在,教授把100个帖子随机放在桶上。他说:“每个贴子Id表示所有木桶中石头数量的百分之一,因此如果木桶A有10个贴子,那么如果Y=100(总石头数量),它最终可以有10个石头。请更改木桶中的石头数量,这样每个木桶中的石头数量最多。转移数量最小的团队(参见下面的TransferAction.class)赢得啤酒!” 这应该是一个常见的分发问题,但我不知道如何解决它。我必须找到一个具有最小更改操作的算法,因此我会进行一些汇总统计,以找出在一些运行/试用/时间内的最佳算法 有人能帮我找到最好的算法吗 有一些限制:因此不可能将所有石头放在一个桶中,然后再放回正确的数量!最起码的意思是,桶A可以将一些石头放在桶B中,但桶B不能再放任何石头了 以下是我目前的代码:Java 搜索算法-桶和石头,java,algorithm,Java,Algorithm,嗨,我正在搜索一个算法来解决以下问题: 有n个桶和y个石头,可以扔进桶里。每个学生在随机的桶中投掷石头x次后,桶中的石头数量不同。现在,教授把100个帖子随机放在桶上。他说:“每个贴子Id表示所有木桶中石头数量的百分之一,因此如果木桶A有10个贴子,那么如果Y=100(总石头数量),它最终可以有10个石头。请更改木桶中的石头数量,这样每个木桶中的石头数量最多。转移数量最小的团队(参见下面的TransferAction.class)赢得啤酒!” 这应该是一个常见的分发问题,但我不知道如何解决它。我
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import org.apache.commons.math3.stat.descriptive.SummaryStatistics;
public class Main {
private static final float Take_Over__Percent_Maximum = 100;
private static Random RANDOM = new Random();
public static void main(String[] args) {
List<Integer> averageSizeList = new ArrayList<Integer>();
int runs = 1000;
for (int i = 0; i < runs ; i++) {
List<TransferAction> transferActions = doSingleRun();
averageSizeList.add( transferActions.size());
System.out.println("The size of transfers:" + transferActions.size());
}
calculateAverage(averageSizeList);
}
private static void calculateAverage(List<Integer> averageSizeList) {
System.out.println();
double[] observed = averageSizeList.stream().mapToDouble(i->i).toArray();
SummaryStatistics sampleStats = new SummaryStatistics();
for (int i = 0; i < observed.length; i++) {
sampleStats.addValue(observed[i]);
}
System.out.println(sampleStats.toString());
}
private static List<TransferAction> doSingleRun() {
// create some buckets
List<Bucket> bucketList = new ArrayList<Bucket>();
int numberOfBuckets = 5;
float percentageOfAllStonesInBucket = Take_Over__Percent_Maximum
/ numberOfBuckets;
for (int i = 0; i < numberOfBuckets; i++) {
Bucket bucket = new Bucket(percentageOfAllStonesInBucket);
bucketList.add(bucket);
}
// now fill buckets with stones
int fillActions = 100;
List<FillAction> fillActionsList = new ArrayList<FillAction>();
for (int i = 0; i < fillActions; i++) {
UUID randomBucketId = bucketList.get(
RANDOM.nextInt(bucketList.size())).getId();
BigDecimal randomAmount = new BigDecimal(RANDOM.nextLong());
FillAction fillAction = new FillAction(randomAmount, randomBucketId);
fillActionsList.add(fillAction);
}
// now try to change the amount of stones in the buckets, so in the end
// every bucket has the right percent of all stones in it
return calculate(bucketList,fillActionsList);
}
private static List<TransferAction> calculate(List<Bucket> bucketList,
List<FillAction> fillActionsList) {
List<TransferAction> transferActions = new ArrayList<TransferAction>();
// the magic should be done here
//...
//...
//now every bucket has maximum percent of all stone or equal stones
return transferActions;
}
}
下一步:
我不清楚你的意思,但我会用一个我理解的例子来理解你的要求 可用石材=x15 铲斗=A+B+C 铲斗A的容量=1/3~33,33%-->这意味着15*(1/3)=5石头 铲斗B的容量=1/3~33,33%-->这意味着15*(1/3)=5石头 铲斗容量C=1/3~33,33%-->这意味着15*(1/3)=5石头 桶中的初始石块(符号0):
A=4 | B=8 | C=3
##### | ##### | #####
# 0 # | # 0 # | # 0 #
# 0 # | # 0 # | # 0 #
# 0 # | # 0 # | # 0 #
# 0 # | # 0 # | # #
# # | # 0 # | # #
# # | # 0 # | # #
# # | # 0 # | # #
# # | # 0 # | # #
##### | ##### | #####
I.简易算法
想法:想象一个桶环
步骤:
1.)取第一个桶,如果达到容量,则取所有额外的石头并将其放入下一个桶中。然后去下一个桶
2.)如果达到第二个铲斗的容量,则将所有附加石料放入下一个铲斗。如果未达到容量。转到下一个桶
已完成:不容易检查,但如果您迭代所有存储桶,并且没有存储桶达到容量,那么您就完成了
例如:
第一步:A中的4块石头。将4块石头移动到B。现在A有0块石头,B有12块石头
4
A -> B
4 0 12
步骤2:A是空的。B有12块石头。现在将7块石头从B移到C。B现在有5块石头和C 10块石头
4 7
A -> B -> C
4 0 12 5 10
步骤3:A是空的。B有5块石头,C有10块石头。现在将5块石头从C移到A。C现在有5块石头,A有5块石头,B还有5块石头
4 7 5
A -> B -> C -> A
4 0 12 5 10 5 5
移动的石头=15
交易=3倍于->
符号
希望你理解我的符号计算方法:-)
II。智能算法 想法:你知道哪个桶达到了容量,哪个桶还有剩余的自由容量 步骤: 1.)迭代所有存储桶,并记住已达到容量的存储桶和额外石头的数量(列表1)。还要记住额外列表(列表2)中剩余的可用容量和可用空间量 2.)迭代列表1并从列表2中获取第一项。然后将超过容量的所有石头从桶A(从列表1)转移到B(从列表2,B可能达到容量!!!)。然后从A中删除铲斗1,从B中删除铲斗2 3.)直到一个列表没有任何项目为止 4.)转到步骤1,然后按照步骤2-4进行操作。如果列表1没有任何剩余项,请完成此操作 例如: 步骤1:List1={B=3}和List2={A=1,C=2}。如果你看一下下一个算法,你就会知道为什么我记得a桶中额外的石头值为3,a桶中缺少的石头值为1,B桶中缺少的石头值为2 步骤2:从列表1中获取B,从列表2中获取A。现在移动3块石头,如下所示。从列表1中删除B,从列表2中删除A。现在列表1为空,请从步骤1开始
3
B -> A
8 5 7
3 2
B -> A -> C
8 5 7 5 5
步骤1迭代2:List1={A=2}和List2={C=2}。看B不在任何列表中
步骤2迭代2:从列表1中获取A,从列表2中获取C。现在移动2块石头,如下图所示。从列表1中删除A,从列表2中删除C。现在列表1为空,请从步骤1开始
3
B -> A
8 5 7
3 2
B -> A -> C
8 5 7 5 5
步骤1迭代3:List1={}和List2={}。看到这两个列表都是空的(但重要的只是列表1),所以我们结束了
移动的石头=5
交易=2倍于->
符号
III.更智能的算法 想法:你知道哪个桶达到了容量,哪个桶还有剩余的自由容量。但是现在我们想起了额外的或丢失的石头的数量,但是看看下面 例如: 步骤1:List1={B=3}和List2={A=1,C=2} 步骤2:
1
B -> A
8 5 5
2
B -> C
8 5 5
完成了。所有水桶现在都有5块石头
移动的石头=3
交易=2倍于->
符号
我的帖子到此结束
也许有更好的算法,但我不知道他们的名字,我不想写更多的解释。但我希望我已经给了你一些可能实现的想法
也许其他人可以用名字来命名一些算法 是否保证你能生产每一个百分比?如果y是17(质数)?是的,为什么不是。你有3个桶和17块石头。也许水桶A有3块石头,B有7块石头,C也有7块石头。你能澄清一下吗:“请更改水桶中的石头数量,这样每个水桶中的石头数量最多。更改率最小的团队”?特别是黑体部分。还有,这些石头怎么移动呢?从一个桶到另一个桶的组?不管移动了多少石头,移动了多远,这算是一次移动吗?@aexerus:因为你不能用50%的石头装满一个桶,所以没有一个完整的百分比可以达到……1)如果有1000块石头,而桶a有10%的可能,那么a可以有100块石头。2.)变化率指=
1
B -> A
8 5 5
2
B -> C
8 5 5