I am unsure how better to title my question, but I'll give a better description.
Let's say I need to distribute a limited quantity of items among a list of objects (called agent
s) where each object has two (relevant) attributes, those being a double agent.price
and an int agent.quantity
. agent.quantity
refers to how many "items" this object "wants" and agent.price
refers to the price it will pay per item.
Now, the way my code is set up is that often times, a lot of agent
s will have equivalent price
attributes, and the way I am distributing the items is that the first agent
with the highest price will have their entire quantity
attribute fulfilled before any other agent
with the same price. That is undesirable.
What I want to happen is that the quantity is distributed in a round robin fashion.
E.g.: let's say agents A and B both have a price
of $1.00 but A has a quantity
of 5 and B a quantity
of 3, and there is only a total of 5 items to give to the agents. Given that both agents are willing to pay equal amounts for the items, I would rather A get 3 items and B get 2 items (or vice-versa) rather than A getting all of the items.
I have come up with a crude implementation of this, but I was wondering if there was a better implementation or if my implementation is flawed.
int indexForSamePriceLevel = 0;
int priceIndex = 0;
while (qToDistribute > 0)
{
if (agents[indexForSamePriceLevel].quantity > 0)
{
agents[indexForSamePriceLevel].quantity--;
qToDistribute--;
}
if (indexForSamePriceLevel 1 != agents.Count)
{
if (agents[indexForSamePriceLevel 1].price == agents[priceIndex].price)
indexForSamePriceLevel ;
else
{
if (agents[indexForSamePriceLevel].quantity == 0)
{
indexForSamePriceLevel ;
priceIndex = indexForSamePriceLevel;
continue;
}
else
indexForSamePriceLevel = priceIndex;
}
}
else
{
if (agents[indexForSamePriceLevel].quantity == 0)
{
indexForSamePriceLevel ;
priceIndex = indexForSamePriceLevel;
continue;
}
else
indexForSamePriceLevel = priceIndex;
}
}
CodePudding user response:
So, I'd recommend getting the price that you're trying to see if the agent
s have, and then looping through them all after you know what price you're looking for.
e.g.
var priceToDistribute = 0; //You get to determine this number
foreach(var agent in agents)
{
if(agent.price == priceToDistribute)
agent.quantity ; //Or quantity--; ? Depending on what you're trying to accomplish.
}
This will loop through every agent with the same price, skipping the ones with a different price, and adjust their quantity only once each loop. You can take this, and put it inside a larger loop that runs until all of the items have been distributed.
CodePudding user response:
No code, just design thinking...
Obviously if totalWeights <= totalAvailable
there's nothing to do except allocate.
Assign all agent
s with the highest price a temporary weight
attribute where weight = price * quantity
? Each agent
gets allocated weight / totalWeights * totalAvailable
items.
Beware of integer vs floating point arithmetic and round/truncate appropriately. I'd suggest integer division and let the last agent get the balance.
e.g. agents with price==1.00
,ob1.quantity==3
,ob2.quantity==5
would get weights 3.0 and 5.0 respectively with totalWeights==8.0
. You would then assign 5*3/8 == 1(or2)
to the first and 5-1(or2)==4(or3)
to the second.