13454awdafasd
如题,我想知道诸如工业之类的MOD的电线是如何判断的?

比如:
1. 如何判断电线是连接起来的
2. 如何判断电线的电量传输和消耗等等

并且我是在用插件开发,类似于Slimefun但又不同(版本: 1.12.2 其他版本兼容无所谓)

洞穴夜莺
本帖最后由 洞穴夜莺 于 2020-9-5 18:00 编辑

这里应该要用到图论
涉及最短路算法
具体就不说了,繁琐得很,不是一天两天能说明白的

roj234
给个思路:
pending = Set.add(起始位置)
pending2 = new Set;
all = new Set;
while(!pending.isEmpty()) {
    for(BlockPos pos : pending) {
        检测电线周边有没有不在all中的电线,有的话加入pending2
    }
    all.addAll(pending);

    tmp = pending;
    pending = pending2;
    pending2 = tmp;
    pending2.clear();
}

电线不能太长什么的自己处理, 此外效率估计不会太高最后返回all,代表所有符合条件的方块

名为123的貘
希腊奶
但是我自己写的话,如果像是凛冰超导之类的玩意,可能会考虑并查集之类的……那样一次更新导线时间复杂度就是O(n=直接连接的导线数)
最短路不难吧……而且这里长度都是1,直接广搜即可。

洞穴夜莺
名为123的貘 发表于 2020-9-5 21:24
希腊奶
但是我自己写的话,如果像是凛冰超导之类的玩意,可能会考虑并查集之类的……那样一次更新导线时间 ...

确实是连通性不难
但是求最短路的时间复杂度高

名为123的貘
洞穴夜莺 发表于 2020-9-5 21:26
确实是连通性不难
但是求最短路的时间复杂度高

可以优化算法使用的次数。
当发生更新的时候,接入机器则所有机器都算一遍路线,导线更改则更新一遍并查集,如果分裂则重新算一遍所有机器的路线。这样也就卡一下下而已。

13454awdafasd
roj234 发表于 2020-9-5 21:14
给个思路:
pending = Set.add(起始位置)
pending2 = new Set;

所以每放一个方块就加入到一个Set里 拆一个方块移除

然后每个方块六个面不断地去遍历去一个一个找最短线路吗?
另外我也在考虑一个导线开一个线程 不过这样消耗似乎非常大
[或者说可以区块? 如果每次放都去遍历的话 多了会很卡吧 还有导线回路会不会导致死循环啥的]

(你说的我实在是没懂..)


13454awdafasd
名为123的貘 发表于 2020-9-5 21:24
希腊奶
但是我自己写的话,如果像是凛冰超导之类的玩意,可能会考虑并查集之类的……那样一次更新导线时间 ...

广搜指一个一个方块去遍历六个面吗 有的话就继续这个操作直到尽头 那怎么判断上面的机器呢

或者有没有办法给一个block加类似于nbt的东西 如果不行的话我就要考虑map了 但是由于我的不同机器是存在不同map里的(早知道用一个map了) 如果用一个map很难区分类型 难道全都继承一个然后最终判断的时候一个一个instanceof吗 会不会过于麻烦

另外一个map中仅仅使用一个location作为key(狭义上的location 仅仅存储了xyzWorld) 会不会有不方便的地方[发现写这些东西考虑的点多又杂]

飞翔之歌
本帖最后由 飞翔之歌 于 2020-9-6 10:16 编辑
13454aw**sd 发表于 2020-9-6 10:10
广搜指一个一个方块去遍历六个面吗 有的话就继续这个操作直到尽头 那怎么判断上面的机器呢

或者有没有办 ...

并查集了解一下,每个导线分属不同的并查集,只需遍历一个方块的六个面并合并即可。

飞翔之歌
本帖最后由 飞翔之歌 于 2020-9-6 10:18 编辑

类似于: 机器-导线 导线-机器导线跟导线分开的,有两个并查集
当导线变成 机器-导线-导线-机器
导线连接,两个并查集合并

13454awdafasd
飞翔之歌 发表于 2020-9-6 10:15
并查集了解一下,每个导线分属不同的并查集,只需遍历一个方块的六个面并合并即可。 ...

本来有点思路了 这么一说又没了 啊这

飞翔之歌
onBlockPlaced() {
  遍历六个面对应的方块
        如果是导线\机器
              获得并查集,将自己合并进去
}

13454awdafasd
飞翔之歌 发表于 2020-9-6 10:20
onBlockPlaced() {
  遍历六个面对应的方块
        如果是导线\机器

这个 并查集 不是很理解 有没有哪里比较详细的讲解地址(az)

飞翔之歌
13454aw**sd 发表于 2020-9-6 10:23
这个 并查集 不是很理解 有没有哪里比较详细的讲解地址(az)

https://blog.csdn.net/qq_27601815/article/details/51426952 并查集,判断是否连通https://blog.csdn.net/yjr3426619/article/details/82315133 带权并查集,判断电力中途损耗等


13454awdafasd
飞翔之歌 发表于 2020-9-6 10:28
https://blog.csdn.net/qq_27601815/article/details/51426952 并查集,判断是否连通https://blog.csdn.ne ...

谢谢 我自己研究一下吧 感谢

(不敢再问了 总感觉再水回复刷金粒。。。。加上我等级这么低)

dbydd
电线的实现有很多种,懒人一点就是每tick都计算电量传输,流畅但是麻烦一点的就像ic那样用各种算法。我是用的worldsaveddata,每个电线网络都有一个唯一的sign,当电线增加/合并/分割/减少的时候会去worldsaveddata根据sign拿数据进行操作,不过这样说实话不能算是很好的解决办法。

dbydd
dbydd 发表于 2020-9-6 10:43
电线的实现有很多种,懒人一点就是每tick都计算电量传输,流畅但是麻烦一点的就像ic那样用各种算法。我是用 ...

至于输入输出电量也是根据sign从worldSavedData拿对应数据进行操作,相当于一个云端的电容库(?)

13454awdafasd
dbydd 发表于 2020-9-6 10:46
至于输入输出电量也是根据sign从worldSavedData拿对应数据进行操作,相当于一个云端的电容库(?) ...

??? 傻了

飞翔之歌

意思就是连通的电线都使用一个标志,当电网发生变化时对标志进行操作,包括输入输出变量也是从标志中获取的

洞穴夜莺
13454awdafasd 发表于 2020-9-6 10:53
??? 傻了

确实是可以的,这样就类似于原版的地图
任何一个人对地图的修改都会反映给所有人

DLumina
本帖最后由 DLumina 于 2020-9-29 20:34 编辑

blog.ustc-zzzz.net/forge-energy-demo-5/
这个里面讲了forge的导线网络实现,用的是连通域方案。不知道是否对楼主有参考价值。

13454awdafasd
DLumina 发表于 2020-9-29 20:30
blog.ustc-zzzz.net/forge-energy-demo-5/
这个里面讲了forge的导线网络实现,用的是连通域方案。不知道是 ...

tks 非常感谢!

第一页 上一页 下一页 最后一页