Simulating loading facilities/charger for electric vehicles in a VRP (with Google OR-Tools) - or-tools

As the title says, I am facing a certain problem with implementing loading facilities in my VRP with time window and capacity constraints. The battery of the electric vehicles is represented by the capacity constraint, so electric vehicles don't visit nodes which would drain their battery live to/below zero.
After implementing nodes that represent bus stops with positive demands, the next step was to simulate loading facilities by implementing nodes with negative demand.
The idea was the following: a charger is represented by a node which 'service time' is 1 [min] and 'demand' is negative (f.ex. 0.5 [kWh]). With this logic, a vehicle could visit the node f.ex. 20 consecutive times to load its battery for 10 [kWh] in 20 [min].
All charger nodes are part of a disjunction, so if a vehicle doesn't need to load its battery, it doesn't have to visit the charger nodes.
So far so good, but the problem is, that this idea of visiting a node multiple times is against the very nature of a VRP, so I came up with the following ideas:
Idea 1:
The first solution I came up with would be to duplicate each charger node by 100 or so, so that there were enough charger nodes for all vehicles to visit and recharge their batteries. In my eyes this is a feasible, but not very elegant solution and it would make my distance matrix even huger, than they already are.
Idea 2:
The next idea I came up with was if it was possible to "reset" the state of specific nodes (in this case the charger nodes) after each routing step. If this was possible, one could reset the "visited state" of the charger nodes after each step (so they would be marked as "not visited") and only implement a duplication of the charger nodes by a number n with n being the number of the vehicles.
Now, even if all vehicles were to load at the same charger at the same time, they were able to rotate through the charger duplicate nodes. In my eyes, this solution would be much more elegant.
Do you think it is possible to implement idea 2? If not, do you think idea 1 would be the only solution for my problem or do you maybe have another ideas to solve this problem?
Thanks for any advice in advance!

Idea 2 is not possible as you can't change the state of a node while the solver is running. In other words, the distance matrix is static.
Idea 1 is how I'd do in OR-Tools. I'd also add penalties to visiting each of them such as to visit as few charging nodes as possible.

Related

Make an idle resource help out a unit already being served

So, the problem I'm facing is the following.
I have a simple arcitechture where I simulate an unloading process where 2 cranes unload incoming docked ships. Using a seize-delay-release design, one incoming ship binds up one capcity point from the "cranes" resourcePool.
View descriptive image here:
In the event of only one arriving ship, how can I make both cranes work on one ship and from there cut the processing time in half?
If a second ship docks in, I want one of the two busy cranes to help out the newly arrived ship with unloading.
Are there any elegant ways of solving this issue?
Another option would be to model the offloading process in a bit more detail. This will negate the requirement of computing the remaining offloading time on a ship if service time depends on the number of cranes serving it in any time unit.
You can model the berths or docks where ships can park to be offloaded as waiting blocks or queues
When a ship enters the docks or berth they will generate a number of containers or what ever units that need to be offloaded in a separate logic stream, using source.inject(numberOfUnits)
You can model the number of cranes available at each berth programmatically by either increasing or decreasing the number of resources in the resource pool using resourcePool.set_capacity(numberOfUnits)
Thus if a ship arrives at a dock A and there is no ship at dock B, you increase the capacity of the cranes at dock A to 2. If a new ship then arrives at dock B you set the capacity for the resource pool at both docks to 1.
If the ship at dock A leaves, then you assign the cranes in the resource pool at dock B to 2 and at dock A to 0, thus simulating the movement of a crane from one dock to another.
The only minor issue here is that if you want to track the utilization of individual cranes you will need to store them separately as you will be destroying and creating resource units the whole time.
Yes, apply priorities. A new ship should have a higher priority and your second crane (still busy with ship 1) can be seized by the higher priority ship using task preemption. (Check how these work in the help and example models)
Only difficulty will be to compute the remaining time on ship 1 if service time depends on the number of cranes serving it in any time unit. Not impossible but will need some coding.

Average result of 50 Netlogo Simulation_Agent Based Simulation

I run an infectious disease spread model similar to "VIRUS" model in the model library changing the "infectiousness".
I did 20 runs each for infectiousness values 98% , 95% , 93% and the Maximum infected count was 74.05 , 73 ,78.9 respectively. (peak was at tick 38 for all 3 infectiousness values)
[I took the average of the infected count for each tick and took the maximum of these averages as the "maximum infected".]
I was expecting the maximum infected count to decrease when the infectiousness is reduced, but it didn't. As per what I understood this happens, because I considered the average values of each simulation run. (It is like I am considering a new simulation run with average infected count for each tick ).
I want to say that, I am considering all 20 simulation runs. Is there a way to do that other than the way I used the average?
In the Models Library Virus model with default parameter settings at other values, and those high infectiousness values, what I see when I run the model is a periodic variation in the numbers three classes of person. Look at the plot in the lower left corner, and you'll see this. What is happening, I believe, is this:
When there are many healthy, non-immune people, that means that there are many people who can get infected, so the number of infected people goes up, and the number of healthy people goes down.
Soon after that, the number of sick, infectious people goes down, because they either die or become immune.
Since there are now more immune people, and fewer infectious people, the number of non-immune healthy grows; they are reproducing. (See "How it works" in the Info tab.) But now we have returned to the situation in step 1, ... so the cycle continues.
If your model is sufficiently similar to the Models Library Virus model, I'd bet that this is part of what's happening. If you don't have a plot window like the Virus model, I recommend adding it.
Also, you didn't say how many ticks you are running the model for. If you run it for a short number of ticks, you won't notice the periodic behavior, but that doesn't mean it hasn't begun.
What this all means that increasing infectiousness wouldn't necessarily increase the maximum number infected: a faster rate of infection means that the number of individuals who can infected drops faster. I'm not sure that the maximum number infected over the whole run is an interesting number, with this model and a high infectiousness value. It depends what you are trying to understand.
One of the great things about NetLogo and some other ABM systems is that you can watch the system evolve over time, using various tools such as plots, monitors, etc. as well as just looking at the agents move around or change states over time. This can help you understand what is going on in a way that a single number like an average won't. Then you can use this insight to figure out a more informative way of measuring what is happening.
Another model where you can see a similar kind of periodic pattern is Wolf-Sheep Predation. I recommend looking at that. It may be easier to understand the pattern. (If you are interested in mathematical models of this kind of phenomenon, look up Lotka-Volterra models.)
(Real virus transmission can be more complicated, because a person (or other animal) is a kind of big "island" where viruses can reproduce quickly. If they reproduce too quickly, this can kill the host, and prevent further transmission of the virus. Sometimes a virus that reproduces more slowly can harm more people, because there is time for them to infect others. This blog post by Elliott Sober gives a relatively simple mathematical introduction to some of the issues involved, but his simple mathematical models don't take into account all of the complications involved in real virus transmission.)
EDIT: You added a comment Lawan, saying that you are interested in modeling COVID-19 transmission. This paper, Variation and multilevel selection of SARS‐CoV‐2 by Blackstone, Blackstone, and Berg, suggests that some of the dynamics that I mentioned in the preceding remarks might be characteristic of COVID-19 transmission. That paper is about six months old now, and it offered some speculations based on limited information. There's probably more known now, but this might suggest avenues for further investigation.
If you're interested, you might also consider asking general questions about virus transmission on the Biology Stackexchange site.

What is a good fitness function for an AI of a zero-sum game?

I am making an AI for a zero-sum 4-player board game. It's actually not zero-sum (the 4 players will "die" when they lose all their lives, so there will be a player who died first, second, third and a player who survived. However, I am telling the AI that only surviving counts as a win and anything else is a lose) After some research, I figured I would use a minimax algorithm in combination with a heuristic function. I came across this question and decided to do the same as the OP of that question - write an evolutionary algorithm that gives me the best weights.
However, my heuristic function is different from the one the OP of that question had. Mine takes 9 weights and is a lot slower, so I can't let the agents play 1000 games (takes too much time) or breed them with the crossover method (how do I do a crossover with 9 weights?).
So I decided to come up with my own method of determining fitness and breeding. And this question is only about the fitness function.
Here are my attempts at this.
First Attempt
For each agent A in a randomly generated population of 50 agents, select 3 more agents from the population (with replacement but not the same agent as A itself) and let the 4 agents play a game where A is the first player. Select another 3 and play a game where A is the second player, and so on. For each of these 4 games, if A died first, its fitness does not change. If A died second, its fitness is increased by 1. If it died third, its fitness is increased by 2. If it survived, its fitness is increased by 3. Therefore, I concluded that the highest fitness one can get is 12 (surviving/wining all 4 games -> 3 + 3 + 3 + 3).
I ran this for 7 generations and starting from the first generation, the highest fitness is as high as 10. And I calculated the average fitness of the top 10 agents, but the average didn't increase a bit throughout the 7 generations. It even decreased a little.
I think the reason why this didn't work is because there's gotta be a few agents that got lucky and got some poor performing agents as its opponents.
Second Attempt
The game setups are the same as my first attempt but instead of measuring the results of each game, I decided to measure how many moves did that agent make before it died.
After 7 generations the average fitness of top 10 does increase but still not increasing as much as I think it should.
I think the reason why this failed is that the game is finite, so there is a finite number of moves you can make before you die and the top performing agents pretty much reached that limit. There is no room for growth. Another reason is that the fitness of the player who survived and the fitness of the player who died third differs little.
What I want
From my understanding of EAs (correct me if I'm wrong), the average fitness should increase and the top performing individual's fitness should not decrease over time.
My two attempts failed at both of these. Since the opponents are randomly selected, the top performing agent in generation 1 might get stronger opponents in the next generation, and thus its fitness decreases.
Notes
In my attempts, the agents play 200 games each generation and each generation takes up to 3 hours, so I don't want to let them play too many games.
How can I write a fitness function like this?
Seven generations doesn't seem like nearly enough to get a useful result. Especially for a game, I would expect something like 200+ generations to be more realistic. You could do a number of things:
Implement elitism in order to ensure the survival of the best individual(s).
The strength of evolution stems from repeated mutation and crossover, so I'd recommend letting the agents play only a few games per generation (say, 5 ~ 10), at least at the beginning, and then evolve the population. You might even want to do only one game per generation.
In this regard, you could adopt a continuous evolution strategy. What this means is that as soon as an agent dies, they are subjected to mutation, and as soon as an agent wins, they can produce offspring. Or any combination of the two. The point is that the tournament is ongoing, everyone can play against anyone else. This is a little more "organic" in the sense that it does not have strictly defined generations, but it should speed up the process (especially if you can parallelise the evaluation).
I hope that helps. The accepted answer in the post you referenced has a good suggestion about the way you could implement crossover.

Data transmission using RF with raspberryPi

I have a project that consisted of transmitting data wirelessly from 15 tractors to a station, the maximum distance between tractor and station is 13 miles. I used a raspberry pi 3 to collect data from tractors. with some research I found that there is no wifi or GSM coverage so the only solution is to use RF communication using VHF. so is that possible with raspberry pi or I must add a modem? if yes, what is the criterion for choosing a modem? and please if you have any other information tell me?
and thank you for your time.
I had a similar issue but possibly a little more complex. I needed to cover a maximum distance of 22 kilometres and I wanted to monitor over 100 resources ranging from breeding stock to fences and gates etc. I too had no GSM access plus no direct line of sight access as the area is hilly and the breeders like the deep valleys. The solution I used was to make my own radio network using cheap radio repeaters. Everything was battery operated and was driven by the receivers powering up the transmitters. This means that the units consume only 40 micro amps on standby and when the transmitters transmit, in my case they consume around 100 to 200 milliamps.
In the house I have a little program that transmits a poll to the receivers every so often and waits for the units to reply. This gives me a big advantage because I can, via the repeater trail (as each repeater, the signal goes through, adds its code to the returning message) actually determine were my stock are.
Now for the big issue, how long do the batteries last? Well each unit has a 18650 battery. For the fence and gate controls this is charged by a small 5 volt solar panel and after 2 years running time I have not changed any of them. For the cattle units the length of time between charges depends solely on how often you poll the units (note each unit has its own code) with one exception (a bull who wants to roam and is a real escape artist) I only poll them once or twice a day and I swap the battery every two weeks.
The frequency I use is 433Mhz and the radio transmitters and receivers are very cheap ( less then 10 cents a pair if you by them in Australia) with a very small Attiny (I think) arduino per unit (around 30 cents each) and a length on wire (34.6cm long as an aerial) for the cattle and 69.2cm for the repeaters. Note these calculations are based on the frequency used i.e. 433Mhz.
As I had to install lots of the repeaters I contacted an organisation in China (sorry they no longer exist) and they created a tiny waterproof and rugged capsule that contained everything, while also improving on the design (range wise while reducing power) at a cost of $220 for 100 units not including batterys. I bought one lot as a test and now between myself and my neighbours we bought another 2000 units for only $2750.
In my case this was paid for in less then three months when during calving season I knew exactly were they were calving and was on site to assist. The first time I used it we saved a mother who was having a real issue.
To end this long message I am not an expert but I had an idea and hired people who were and the repeater approach certainly works over long distances and large areas (42 square kilometres).
Following on from the comments above, I'm not sure where you are located but spectrum around the 400mhz range is licensed in many countries so it would be worth checking exactly what you can use.
If this is your target then this is UHF rather than VHF so if you search for 'Raspberry PI UHF shield' or 'Raspberry PI UHF module' you will find some examples of cheap hardware you can add to your raspberry pi to support communication over these frequencies. Most of the results should include some software examples also.
There are also articles on using the pins on the PI to transmit directly by modulating the voltage them - this is almost certainly going to interfere with other communications so I doubt it would meet your needs.

How to increase the vehicle density in Veins-lte during simulation

I would like to increase the number of vehicles per area i.e vehicle density. In case of veins; the number of vehilces as well as speed can be increased or decreased via erlagen.rou.xml. I tried to change the number of vehicles from heterogeneous.rou.xml, but i faced some errors like :
Error in module (HeterogeneousToLTE) scenario.node[1].heterogeneousToLTE (id=89) at event #192976, t=20.6: IPvXAddressResolver: module `node[21]' not found
How to solve this issue?
Thanks
To increase the number of vehicles you have to generate/build a new scenario for SUMO. Veins LTE only covers the network simulation part.
The error you posted has a different reason: You are trying to send a message to a node that does not yet exist. To fix this, you have to change either the provided SimpleApp.cc, or even better, write your own application.