Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 农民需要通过自参考动物表循环的算法_C#_Algorithm_Design Patterns_Database Design - Fatal编程技术网

C# 农民需要通过自参考动物表循环的算法

C# 农民需要通过自参考动物表循环的算法,c#,algorithm,design-patterns,database-design,C#,Algorithm,Design Patterns,Database Design,问题:农场里有很多动物。每种动物都可以有任意数量的动物朋友,反社会动物除外——它们没有属于自己的朋友,但它们作为朋友属于其他正常动物。每一种动物都和它最不快乐的动物朋友一样快乐,当然除了反社会的动物。反社会动物的快乐水平可以是任何东西 一天早上,所有的动物醒来,发现一些反社会动物的情绪发生了变化。农夫是如何计算出每只动物的幸福感的 这里是农场工人们所能看到的(他们没有上过农民学校): DataTable animals=选择所有动物(); foreach(动物中的动物数据行。行) { int

问题:农场里有很多动物。每种动物都可以有任意数量的动物朋友,反社会动物除外——它们没有属于自己的朋友,但它们作为朋友属于其他正常动物。每一种动物都和它最不快乐的动物朋友一样快乐,当然除了反社会的动物。反社会动物的快乐水平可以是任何东西

一天早上,所有的动物醒来,发现一些反社会动物的情绪发生了变化。农夫是如何计算出每只动物的幸福感的

这里是农场工人们所能看到的(他们没有上过农民学校):

DataTable animals=选择所有动物();
foreach(动物中的动物数据行。行)
{
int worstMood=10;//超级快乐!
DataTable friendRecords=选择动物朋友((int)Animal[“AnimalID]”);
foreach(friendRecords.Rows中的DataRow friend)
{
DataTable animalFriends=选择_AnimalFriend((int)friend[“AnimalID_friend”);
foreach(animalFriends.Rows中的DataRow animalFriend)
{
int animalMood=获得动物的情绪((int)animalFriend[“情绪”);
if(动物性<苦艾)
{
艾草=动物性植物;
}
}
}
}
但这将不起作用,因为动物表不按顺序遵循已形成的动物朋友层次结构。动物可以在任何时候交朋友!所以动物(1)可能有动物(4000)作为朋友。动物(1)不会显示准确的情绪,因为它会在动物(4000)的情绪更新之前检查动物(4000)的情绪。每天都有新的动物被丢弃。我想这个解决方案可能是一个普通的算法设计,但我一直没能找到它。我不相信我有正确的术语来准确地搜索它

非常感谢,如果这个问题已经得到了回答,那么很抱歉

添加:

下面是犹太人区可能的关系图表:

反社会动物处于底层,没有属于它们的朋友。正常的动物到处都是。正常的动物友谊没有确切的结构,除非(正如塞巴斯蒂安指出的)不可能有一个闭环(如果设计正确的话)


每周将增加数十万只动物,处理速度是一个关键因素

问得好。所以,如果我理解正确的话,你们基本上有带圈的有向图。您可以将每个动物都视为一个节点(顶点),该节点具有其情绪所依赖的动物的传出边,以及其情绪所影响的动物的传入边。显然,反社会动物只会有来袭的边缘

如果你这样想,你会注意到两件事

1) 你可以设计一个迭代算法,扫描所有动物,检查每只动物是否有任何向外的边缘,只针对它的社交或已经处理的动物。如果是,我们计算动物的情绪,并将其标记为已处理。如果没有,我们就跳过这个迭代

2) 因为您的图中可以有循环,所以此算法不会总是完成。也就是说,你可以让动物A依赖于B,B依赖于C,C依赖于A。如果你有简单的逻辑,比如在你的例子中,最低情绪获胜,你可能会通过分配给循环中的所有动物来检测和解决这些循环-在这种情况下,A,B,C最低共同情绪


希望有帮助

有趣的问题。如果我理解正确的话,每只动物的幸福是所有动物幸福的最小值,如果它是单向的朋友(入境)

如果是这样的话,那么挑战在于每一只动物的朋友的幸福都取决于他们的朋友,依此类推,从哪里开始呢

这是我第一眼看到的

因为每天都会有新的动物出现,所以你需要每天重新开始,并且你需要从快乐程度最低的动物开始。很容易找到它们,然后把快乐传播给所有它们是朋友的动物,相应地调整它们的快乐水平。然后取所有调整后的动物,重复上述步骤,直到不再调整动物。一旦这个快乐水平被完全传播,移动到下一个最高的快乐水平并重复,直到剩下的最高快乐水平被处理

有趣的是,哪种动物(如果有的话)是反社会的并不重要。它们只是没有影响输入的动物,因此不会被这个过程调整

我认为这会让你达到你想要的目的,编写代码应该一点也不困难


希望能有所帮助。

首先抓起所有反社会的动物,从最不快乐的动物到最快乐的动物。将所有群居动物的幸福感初始化为最大值(这使一切变得更容易,因为你不必检测以前不幸福的动物何时变得更幸福)。然后,只需在列表上迭代,并将快乐水平传播到友谊链上:

void UpdateFarm()
{
    // Start with a list of antisocial animals from least to most happy.
    var antisocialAnimals = GetAntisocialAnimals().OrderBy(x => x.Happiness);

    // Initialise the social animals to the global maximum. Note the
    // global maximum is the happiest antisocial animal. This is done to
    // avoid the case where an antisocial animal's happiness has increased,
    // so some of the social animals are too unhappy.
    var maxHappiness = antisocialAnimals.Last().Happiness;
    var socialAnimals = GetSocialAnimals();
    foreach (var socialAnimal in socialAnimals)
        socialAnimal.Happiness = maxHappiness;

    // Now iterate from least to most happy, propagating up the friend chain.
    foreach (var antisocialAnimal in antisocialAnimals)
        UpdateFriends(antisocialAnimal);
}

// To propagate a happiness change, we just find all friends with a higher
// happiness and then lower them, then find their friends and so on.
void UpdateFriends(Animal animal)
{
    var friends = GetFriends(animal); // Friends with this animal, not friends of.

    foreach (var friend in friends.Where(x => x.Happiness > animal.Happiness))
    {
        friend.Happiness = animal.Happiness;

        // Since this friend's happiness has changed, we now need to update
        // its friends too.
        UpdateFriends(friend);
    }
}
  • 如果反社会动物的情绪是绝对最低的,那么它的所有朋友和朋友的朋友都会继承它压倒一切的坏情绪
  • 如果反社会动物的情绪处于绝对最低的第二位,那么它的所有朋友和朋友的朋友都将继承它的情绪,前提是他们还不是绝对最低情绪动物的朋友/朋友
因此,建议采用以下算法:

首先,您将社交动物的情绪设置为MAX_MOOD,然后循环遍历反社会动物以增加情绪,并递归更新其所有朋友和朋友的朋友的情绪。如果在递归过程中没有更新情绪,那么可以停止
void UpdateFarm()
{
    // Start with a list of antisocial animals from least to most happy.
    var antisocialAnimals = GetAntisocialAnimals().OrderBy(x => x.Happiness);

    // Initialise the social animals to the global maximum. Note the
    // global maximum is the happiest antisocial animal. This is done to
    // avoid the case where an antisocial animal's happiness has increased,
    // so some of the social animals are too unhappy.
    var maxHappiness = antisocialAnimals.Last().Happiness;
    var socialAnimals = GetSocialAnimals();
    foreach (var socialAnimal in socialAnimals)
        socialAnimal.Happiness = maxHappiness;

    // Now iterate from least to most happy, propagating up the friend chain.
    foreach (var antisocialAnimal in antisocialAnimals)
        UpdateFriends(antisocialAnimal);
}

// To propagate a happiness change, we just find all friends with a higher
// happiness and then lower them, then find their friends and so on.
void UpdateFriends(Animal animal)
{
    var friends = GetFriends(animal); // Friends with this animal, not friends of.

    foreach (var friend in friends.Where(x => x.Happiness > animal.Happiness))
    {
        friend.Happiness = animal.Happiness;

        // Since this friend's happiness has changed, we now need to update
        // its friends too.
        UpdateFriends(friend);
    }
}
public void MoodCalculator()
{

 /** Reasoning:
 * 
 * The unidirectional cyclic graph can be also expressed as multiple friend 
 * trees where
 * anti-social animal is the root node of a friend tree. Because a social animal's
 * mood is that of its lowest mood friend this means that regardless of the 
 * tree depth of an animal
 * it's mood is that of the mood of the lowest mood antisocial animal 
 * who's tree it is a member of.  
 * 
 * */

  SortedList<int, List<Animal>> moodGroups = new SortedList<int, List<Animal>>();

  HashSet<Animal> allAnimals = new HashSet<Animal>();

  //get all antisocial animals and group according to mood
  //work from low to high mood
  forach(Animal a in GetAllAntiSocialAnimalsFromDb()) 
  {
     if(!moodGroups.ContainsKey(a.Mood)) moodGroups.Add(a.Mood, new List<Animal>());
     moodGroups[a.Mood].Add(a);
  }

  foreach(var item in moodGroups)
  {
     //add our root antisocial animals to master group
     foreach(Animal a in item.Value) allAnimals.Add(a);

     //recurse over tree starting at antisocial animal roots
     TreeRecurse(item.Value, allAnimals, item.Key);
  }


 }

 public void TreeRecurse(List<Animal> children, List<Animal> allAnimals, int mood)
 {
    //can look for list as we are just grouping everything and don't care about tree 
    //structure
    //db call should only get unique/distinct animals
    List<Animal> parentAnimals = GetParentAnimalsOfChildAnimalListFromDb(children);
    //remove animals from from parents if they are already in the allAnimal set
    //working from low mood to high we can ignore animals that have appeared in a 
    //lower mood tree
    parentAnimals.RemoveAll(a => allAnimals.Contains(a));
    //add animals to allAnimals and set mood
    foreach (Animal a in parentAnimals)
    {
       a.Mood = mood;
       allAnimals.Add(a);
    }
    //end recurse
    if (parentAnimals.Count == 0) return;
    //recurse
    else TreeRecurse(parentAnimals, allAnimals, mood);
   }