看下这个组合算法,java里写算法真不容易

aipb2008 2008-05-06 03:39:29

public class Algorithms {

public Algorithms() {
}

private static <T> void subCombination(List<List<T>> out,List<T> in,
List<T> temp,int index,int nloop,int nth){
if (index == nth){ //get the result
out.add(temp);
System.out.println(temp);
}
else{
for (int loop = nloop;loop < in.size();++loop){
temp.set(index,in.get(loop));
subCombination(out,in,temp,index+1,loop+1,nth); //backtracking
}
}
}

public static <T> void combination(List<List<T>> out,List<T> in,int nth){
if (nth >= in.size())
return;
List<T> temp = new ArrayList<T>(nth);
for (int i = 0;i < nth;++i)
temp.add(null);
subCombination(out,in,temp,0,0,nth);
}

public static void main (String[] args) {
List<String> ls = new ArrayList<String>();
ls.addAll(Arrays.asList("a","b","c","d","e","f","g","h"));
List<List<String>> comb = new ArrayList<List<String>>();
combination(comb,ls,7);
System.out.println(comb);
}
}


输出:

[a, b, c, d, e, f, g]
[a, b, c, d, e, f, h]
[a, b, c, d, e, g, h]
[a, b, c, d, f, g, h]
[a, b, c, e, f, g, h]
[a, b, d, e, f, g, h]
[a, c, d, e, f, g, h]
[b, c, d, e, f, g, h]
[[h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h], [h, h, h, h, h, h, h]]


输出的两部分,其中前面正确的结果是因为在算法中检测输出结果,而后面错误的输出是实际提取出来的组合结果。

问题1:
我知道错误的原因是因为“浅拷贝”的问题,在out.add(temp);一句中,out中的结果和temp做了个映射,而temp是不断改变的。
我想知道在此处用“深拷贝”该如何实现?进一步,java中对象“深拷贝”的实现。

注:不仅是那里,因为浅拷贝的原因,使得方法返回的结果和输入建立映射,改变其一,会引起另一不期望的改变。

问题2:
总所周知,java的泛型不允许创建泛型数组,即T[] temp = new T[nth];所以我把temp实现为List<T>,并且因为要使用set来改变位置元素,所以很别扭的采用一个for循环再赋值null的方法。其实很不想这样做,有没有什么更好的方法实现temp这个变量?


………………………………………………………………………………………………………………………………………………
这是个使用递归回溯的计算组合的算法,闲来没事用java实现下,准备放进我的库里。这个算法用c++我是实现过的,也是用的泛型。
大家帮下忙,我没接触过java中的数据结构和算法,代码里的不合理的地方希望指导一下。
...全文
469 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
aipb2008 2008-05-08
  • 打赏
  • 举报
回复
问的差不多了,结贴。
mdog26 2008-05-07
  • 打赏
  • 举报
回复
up下
xihakuyi 2008-05-07
  • 打赏
  • 举报
回复
不懂
正好学习学习哦
谢谢
aipb2008 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hongke1490 的回复:]
第一个问题:深拷贝比较复杂,涉及到递归,用clone实现吧。
把out.add(temp)改成下面就可以了。
out.add((List <T>)((ArrayList)temp).clone());
第二个问题:虽然T[] temp = new T[nth]不行,但可以这样;
Ojbect[] os = new Object[nth];
T[] temp = (T[])os;
完整程序

Java code
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public cl…
[/Quote]

谢谢你的解答,你的解决可以很好的完成。但是还有点疑问。
用clone我也想过,但是这里我是用的String去实例化运行这个程序,要是是一个自定义类型,该类型又包含非基本类型的域,如果该类没有去实现Cloneable接口,又或者实现了,但是其包含的域没有实现Cloneable接口,一样会有“浅拷贝”存在。
也许是我太钻牛角尖了,但是我想即使采用clone来实现,有可以保护这种情况,也就是说在不能进行深拷贝的对象,我在方法中抛出个异常,这样不知道能否实现。


对于第2个问题,我确实不知道,因为我理解的泛型类型参数会被擦除,所以在转型时不能使用,但是居然可以,只是有个unchecked的警告,用@SuppressWarninis可以禁止。
jayflee 2008-05-07
  • 打赏
  • 举报
回复



private static <T> void subCombination(List<List<T>> out,List<T> in,
List<T> temp,int index,int nloop,int nth){
if (index == nth){ //get the result
out.add(temp);
System.out.println(temp);
}
else{
for (int loop = nloop;loop < in.size();++loop){
List<T> temp1=new ArrayList<T>(temp);

//我晕上面subCombination()的不对
//因为index等于temp1.size()
//搞得自己没看懂程序

temp1.add(in.get(loop));

subCombination(out,in,temp1,index+1,loop+1,nth); //backtracking
}
}
}

hongke1490 2008-05-07
  • 打赏
  • 举报
回复
第一个问题:深拷贝比较复杂,涉及到递归,用clone实现吧。
把out.add(temp)改成下面就可以了。
out.add((List<T>)((ArrayList)temp).clone());
第二个问题:虽然T[] temp = new T[nth]不行,但可以这样;
Ojbect[] os = new Object[nth];
T[] temp = (T[])os;
完整程序

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

public class Algorithms
{

public Algorithms()
{
}

private static <T> void subCombination(List<List<T>> out, List<T> in,
T[] temp, int index, int nloop, int nth)
{
if (index == nth)
{ // get the result
out.add(Arrays.asList(temp.clone()));
System.out.print("[");
for(int i=0;i<temp.length-1;i++)
System.out.print(temp[i]+", ");
System.out.print(temp[temp.length-1]+"]");
System.out.println();
}
else
{
for (int loop = nloop; loop < in.size(); ++loop)
{
//temp.set(index, in.get(loop));
temp[index] = in.get(loop);
subCombination(out, in, temp, index + 1, loop + 1, nth); // backtracking
}
}
}

public static <T> void combination(List<List<T>> out, List<T> in, int nth)
{
if (nth >= in.size())
{
return;
}
//List<T> temp = new ArrayList<T>(nth);
Object[] os = new Object[nth];
T[] temp = (T[])os;
// for (int i = 0; i < nth; ++i)
// temp.add(null);
subCombination(out, in, temp, 0, 0, nth);
}

public static void main(String[] args)
{
List<String> ls = new ArrayList<String>();
ls.addAll(Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h"));
List<List<String>> comb = new ArrayList<List<String>>();
combination(comb, ls, 7);
System.out.println(comb);
}
}
udcasking 2008-05-07
  • 打赏
  • 举报
回复
帮顶
jayflee 2008-05-07
  • 打赏
  • 举报
回复
2、没想到好方法 不过变通一下也可以实现


private static <T> void subCombination(List<List<T>> out,List<T> in,
List<T> temp,int index,int nloop,int nth){
if (index == nth){ //get the result
out.add(temp);
System.out.println(temp);
}
else{
for (int loop = nloop;loop < in.size();++loop){
List<T> temp1=new ArrayList<T>(temp);

//这里改了
if(index>temp1.size()){
temp1.set(index,in.get(loop));
}else{
temp1.add(in.get(loop));
}

subCombination(out,in,temp1,index+1,loop+1,nth); //backtracking
}
}
}

public static <T> void combination(List<List<T>> out,List<T> in,int nth){
if (nth >= in.size())
return;
List<T> temp = new ArrayList<T>(nth);

subCombination(out,in,temp,0,0,nth);
}
jayflee 2008-05-07
  • 打赏
  • 举报
回复
1、修改subCombination


private static <T> void subCombination(List<List<T>> out,List<T> in,
List<T> temp,int index,int nloop,int nth){
if (index == nth){ //get the result
out.add(temp);
System.out.println(temp);
}
else{
for (int loop = nloop;loop < in.size();++loop){
List<T> temp1=new ArrayList<T>(temp);//。。。。。。。。。。
temp1.set(index,in.get(loop));
subCombination(out,in,temp1,index+1,loop+1,nth); //backtracking
}
}
}
hongke1490 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 aipb2008 的回复:]
也许是我太钻牛角尖了,但是我想即使采用clone来实现,有可以保护这种情况,也就是说在不能进行深拷贝的对象,我在方法中抛出个异常,这样不知道能否实现。
[/Quote]
嗯,对于一个List要实现完全的深拷贝确实比较麻烦,因为你根本不知道List里面放的到底是什么类型数据,要根据具体情况采用不同的方法。用抛出异常应该也是一个解决方法,我觉得应该是可行的。你可以试试看。不过,你捕获到这个异常后怎么处理呢?
loujianchengdd 2008-05-06
  • 打赏
  • 举报
回复
顶一下
aipb2008 2008-05-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 java2000_net 的回复:]
能用就好!
[/Quote]

就是不能用啊,后半部分输出是错误的。求解中……
谢谢帮顶的。
qq278095755 2008-05-06
  • 打赏
  • 举报
回复
我也顶...
anqini 2008-05-06
  • 打赏
  • 举报
回复
输出结果很漂亮!
wcj1981 2008-05-06
  • 打赏
  • 举报
回复
什么叫深拷贝,是不是override clone method就行了。
DoomGT 2008-05-06
  • 打赏
  • 举报
回复
帮顶一下~~~
Brokenfango 2008-05-06
  • 打赏
  • 举报
回复
有意思
Binary Wang 2008-05-06
  • 打赏
  • 举报
回复
有点深奥,看不懂,帮你顶
haoxiongok 2008-05-06
  • 打赏
  • 举报
回复
帮楼主顶一个
老紫竹 2008-05-06
  • 打赏
  • 举报
回复
能用就好!
加载更多回复(3)
内容概要:本文围绕不确定环境下的多式联运路径优化问题展开研究,提出并实现了基于AFO算法、遗传算法(GA)和粒子群优化算法(PSO)的三种智能优化方法,并借助Matlab平台完成算法编程与仿真。研究构建了考虑时间、成本、转运风险等多重不确定因素的路径优化模型,系统比较了AFO、GA、PSO三种算法在收敛速度、全局寻优能力和稳定性方面的表现,同时引入Matlab自带的全局优化搜索器作为基准对照,深入分析各算法在复杂物流网络中的适用边界与性能差异。研究表明,AFO算法在解决此类组合优化问题时展现出更快的收敛效率和更强的局部规避能力。; 适合人群:具备一定Matlab编程基础与运筹优化知识,从事物流工程、交通运输规划、智能算法开发等相关领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于多式联运、综合货运网络中的路径决策支持系统构建;②为不确定性条件下复杂路径规划问题提供智能算法选型依据与技术实现方案;③支持科研人员复现主流优化算法并开展横向性能对比实验,推动算法改进与实际落地。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析算法实现流程,重点理解目标函数设计、约束条件处理及参数敏感性分析部分,可通过调整问题规模与算法参数进行对比实验,进一步拓展至动态路径规划或大规模网络优化等延伸场景。
内容概要:本文研究了基于QLearning自适应强化学习的PID控制器在自主水下航行器(AUV)运动控制中的应用,通过Matlab代码实现了控制算法的仿真验证。该方法融合强化学习的在线自适应能力与传统PID控制的稳定性优势,利用QLearning算法动态优化PID控制器的比例、积分、微分参数,以应对水下复杂流体环境、模型不确定性及外部干扰等挑战,从而提升AUV轨迹跟踪的精度、鲁棒性与动态响应性能。文中系统阐述了AUV的六自由度非线性动力学建模过程、QLearning算法的状态空间与动作空间设计、奖励函数构造及训练机制,并详细说明了PID参数自整定的闭环控制架构。仿真结果表明,相较于传统固定参数PID控制器,该智能控制策略在多种工况下均展现出更优的控制效果,有效抑制了超调,加快了响应速度,并增强了抗干扰能力。; 适合人群:具备自动控制理论、强化学习基础及Matlab/Simulink仿真能力,从事水下机器人、智能控制、海洋工程、自动化等领域的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于AUV、UUV等无人水下平台的高精度自主导航与运动控制;②为解决非线性、强耦合、时变系统的控制器参数自适应整定问题提供智能化解决方案;③作为强化学习与经典控制理论深度融合的技术范例,推动智能控制算法在海洋装备中的工程化应用。; 阅读建议:建议读者结合提供的Matlab代码深入理解算法实现细节,重点剖析QLearning的状态-动作-奖励机制设计、PID参数更新逻辑及仿真对比实验结果,有条件者可在更复杂的动力学模型或实际硬件平台上进一步验证与优化算法性能。

62,622

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧