원래 질문글

https://gall.dcinside.com/mgallery/board/view/?id=factorio&no=15972&page=1


내가 생각해낸거 아님. 나도 여기 갤러중 썩은물 한명 서버 들어가서 신기해서 물어보고 무릅탁침

Source : https://gall.dcinside.com/mgallery/board/view?id=factorio&no=15929




문제점 : 역이름을 동일하게 설정하여 다수의 기차를 운용하려고 하면, 열차가 한 역에 몰리는 현상이 생기며,

이로 인해 대기열을 뛰어 넘어서 기차가 대기하면서 선로가 막힘.



원인 : 기차경로는 path finding penalty 에 따라 설정되는데, 이 페널티값은 음수이며 음수가 가장 적은 경로를 찾는다는게 기본 로직임.

자세한건 https://wiki.factorio.com/Railway/Train_path_finding 여기서 어떤 조건에서 얼마의 페널티가 부과되나 확인 가능.


위 상황에서 문제가 발생하는 원인은, 동일 이름의 역 중 먼곳의 역이 가지는 페널티값이 가까운 역보다 크기 때문에 발생함.

가까운 곳의 페널티가 더 낮으니, 거기로 몰빵해서 가버리는거임.


이를 해결하기 위해선 더미스테이션을 배치하는 방법을 쓸 수 있는데, 그러기 위해서 3가지를 구현해야함.


1. 기차역 회로네트워크 활성화 / 비활성화 허용 A(나머지 조건과 관계없으니 필요하면 나머지조건 써서 니가 필요한 회로 구성해도 됨. 기차내용물이나 기차ID읽는 그런거)


2. 더미스테이션의 배치.


3. 대기열 내에서 회차 금지.

(대기열에 대기하다가, 역 상황에 따라 바로 앞에 역으로 들어가지 않고 다시 본선으로 돌아가서 다른 역으로 빠져나가는 우회선로를 구성하는 것)






대충 어떻게 생겼는가?




신경써야할 점

- 본선과 대기열 사이 신호

- 대기열 진입부분 일반신호 회로연결해서 빨강불 몇개인지 확인하기 위해 일반신호에 회로연결

- 더미스테이션 설치

- 실제 사용할 역 회로조건으로 ON/OFF 설정



더미스테이션이란 무엇인가? : 기차역이 배치되어있긴 하나, 실제로 사용하진 않는, 기차경로설정의 강제성을 위한 역임.



대략적인 구성은 위와 같음.


대기열 -> 더미스테이션 분기점 -> 실제 사용할 역








대기열 셋팅




평범한 대기열 셋팅임. 다만,

1번. 더미스테이션으로 진입하는 분기점에 연속신호를 박아서 더미스테이션으로의 진입을 차단하는 구조를 갖추자.

2번. 그리고 대기열 진입부분에다가 대기열이 찬 수 만큼 빨간신호를 읽을 수 있게 회로전선을 연결해서 실제 사용할 역까지 끌고가자.

3번. 더미역과 실제역 사이에 분기점을 만들어서 연속신호를 하나 박자.





더미스테이션 셋팅



첫째로, 일반신호를 여러개 박고 강제로 닫힘 신호를 주는 이유 : 그냥 나는 강조하려고 만들어봄. 별 의미 없음. 페널티값이 증가하긴 하지만 이미 닫힌 선로기 때문에 큰 의미없음.


일반신호 한개만 달고, 강제로 닫힘 신호를 주게 일정신호기로 빨강 =1 일때, 신호를 닫아라 라는 회로만 구성해주면 됨. 이렇게 하면 아까 말한 더미스테이션 분기점 연속신호가 파랑색으로 바뀌면 됨.(좌측 하단 보이지?)


연속신호 파랑색 = 내 앞 구간에 갈 수 있는 길과 갈 수 없는 길이 동시에 존재한다. 이 경우 갈 수 없는길은 더미스테이션이고, 갈 수 있는 길은 실제 니가 쓸 역이 되겠지



둘째로, 더미스테이션 구역에 역을 2개 만들어놓으셈.



더미스테이션 구역에 역이 2개 있고, 실제 사용할 역 이름과 동일. 앞쪽은 항상 살리고 뒷쪽은 항상 죽여놓기.



이런식으로 만드들면 되는데, 두 역 중 앞쪽역은 회로 연결하지 말 것. 항상 켜두기 위함임.

뒷쪽 역은 회로연결해서 항상 꺼둘 것.(지도상에 꺼져있는 동일이름 역이 하나도 없을때, 강제 경로탐색(force repath)위해서임)





실제 사용할 역 회로조건 설정




활성화/비활성화 + 기차에 신호보냄 체크해놓기



활성화 / 비활성화 - 이 역 말고, 다른 동일한 이름의 역의 하차지점으로 나머지 기차들을 돌리려면 역이 비활성화 상태가 되어야함.

안그러면 여기로 계속 꾸역꾸역 와서 대기열 앞에 본선까지 처묵처묵하면서 줄스겠지?


스샷에선 점을 잘못찍었는데, 정차한 기차 읽기는 상관없음. 미안. 졸려서 잘못찍음.





그리고 이 역을 껐다 켰다 하는 회로 설명임.

설명의 편의를 위해 역은 철판 100개의 버퍼를 유지한다고 가정하도록 하자.


이 역이 가질 수 있는 경우의 수는 4개임

1. 대기열 비어있고, 역 화물 버퍼 여유있음. → 역 활성화. ( 본선에서 접근중인 기차에 경로탐색 허용 )

2. 대기열 비어있고, 역 화물 버퍼 꽉찼음. → 역 비활성화 (경로탐색 비활성. 이 역에 화물이 충분하니 다른 역으로 가십셔)

3. 대기열 꽉찼고, 역 화물버퍼 여유있음 → 역 활성화 ( 대기열에 있는 기차에 경로탐색 허용 )

4. 대기열 꽉찼고, 역 화물버퍼 꽉찼음. → 역 비활성화 (경로탐색 비활성. 입구컷.)



화물버퍼 확인용 비교조합기

테스트 편의를 위해 상자가 아닌 일정조합기 썼음.

니가 정한 화물(Cargo)허용량을 넘을경우, C=1 출력




대기열 여유용량 확인용 비교조합기

여기선 테스트 편의를 위해 일정조합기를 넣었으나, 실제로 사용할땐 대기열 일반신호기에 물린 전선을 그대로 꼽으셈

대기열(Waiting line) 빨간불 = 7 일때(테스트 대기열이 7개임), W=1 출력



두 조건을 비교할 비교조합기

각각의 조건이 1 보다 크다면, T=1 출력


그리고 우리가 실제 사용할 역은 T=0 (NULL. 입력없음) 일 경우, ON 상태로 설정해 놨음을 기억하자.


여기서, "각각(노란별표)" 은 입력된 신호 두가지를 각각 비교하여, 두 입력값 모두 참일 경우는 참값을, 그렇지 않은 경우는 거짓값을 배출함.

둘중 하나만 참인 경우는 초록별표나 빨간별표 둘중 알맞은걸 사용해야한다. 둘다 쓰임새가 다름.

아 근데 뭔가 저 두개중에 하나 사용해서 간단하게 만들수있을거같기도 한데 그건 나중에 알아보자. 대가리아픔.


다시 돌아와서,


따라서,

C=1(화물꽉참) / W=1(대기열꽉참) 인 경우 T=1 → 역 비활성화(경로탐색 비활성)

C=0 (화물부족) / W=1 (대기열꽉참) 인 경우 T=0 → 역 활성화(대기열꺼 끌어오기)

C=1(화물꽉참 / W=0 (대기열 여유있음) 인 경우 T=0 → 역 활성화(모든 열차들에게 경로탐색 허용)

C=0 (화물부족) / W=0(대기열 여유있음) 인 경우 T=0 역 활성화(모든 열차들에게 경로탐색 허용)



--------------------------------


이게 완료됬고, 대기열 내 회차로를 통해 본선으로 다시 되돌아갈 수 있는 뒷구멍이 없게 대기열을 만들었다면,

이제 동일한 이름의 역 다수를 이용해도 역이 꺼졌다고 갑자기 열차들이 전부 상차역으로 달려가거나,

역이 켜졌다고 모든 기차가 한 역에 몰빵해서 선로를 막아버리는 일은 없을것임.


왜냐하면, 우리가 대기열에서 더미스테이션으로 이어지는 설계를 하면서


열차들이 대기열에 꽉 참 -> 역 꺼짐 -> 대기열에 머무르던 기차들은 도망갈 곳이 없음. 꺼진 역이 켜질때까지 기다려야함.

왜냐하면 바로 앞에 꺼진 역보다 더 가까이 켜져있지만, 진입할 수 없는 더미스테이션이 존재해서 강제로 경로를 고정해주거든.


비유하자면 양갈래길 중 선택해야하는데, 두 길 모두 낙석으로 막혀있고 그 앞에서 존버타야하는거임



이런식으로.





근데 만약 실제로 사용할 동일이름의 역이 모두 OFF상태이다, 그럴 경우 어떻게 될까?

그건 나도 모르겠음.


근데 맨 첨에 본선에서 대기열 진입하는 구간을 중간진입 못하게 빨간불로 막아놨으니, 알아서 경로설정 다시해서 남은 대기열로 착착착 돌아가지 않을까?